最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Keep objects as a grouped based on duplicate value in array of object - Stack Overflow

programmeradmin0浏览0评论

This is the input array of object:

var array = [{
    id: 1,
    name: 'A',
    family: 'B',
    number: 100,
    category: 'test',
    time: '2018-03-02T10:33:00.000Z'
  },
  {
    id: 2,
    name: 'A',
    family: 'B',
    number: 100,
    category: 'test',
    time: '2018-03-02T10:33:50.000Z'
  },
  {
    id: 3,
    name: 'A',
    family: 'B',
    number: 100,
    category: 'test',
    time: '2018-03-02T10:34:30.000Z'
  },
  {
    id: 4,
    name: 'A',
    family: 'B',
    number: 100,
    category: 'test',
    time: '2018-03-02T10:36:00.000Z'
  },
  {
    id: 5,
    name: 'A',
    family: 'C',
    number: 250,
    category: 'other',
    time: '2018-03-02T10:33:00.000Z'
  },
  {
    id: 6,
    name: 'A',
    family: 'C',
    number: 250,
    category: 'other',
    time: '2018-03-02T10:33:05.000Z'
  }
]

I want to group it like this as output:

var output = [
  [{
      id: 1,
      name: 'A',
      family: 'B',
      number: 100,
      category: 'test',
      time: '2018-03-02T10:33:00.000Z'
    },
    {
      id: 2,
      name: 'A',
      family: 'B',
      number: 100,
      category: 'test',
      time: '2018-03-02T10:33:50.000Z'
    },
    {
      id: 3,
      name: 'A',
      family: 'B',
      number: 100,
      category: 'test',
      time: '2018-03-02T10:34:30.000Z'
    },
    {
      id: 4,
      name: 'A',
      family: 'B',
      number: 100,
      category: 'test',
      time: '2018-03-02T10:36:00.000Z'
    }
  ],
  [{
      id: 5,
      name: 'A',
      family: 'C',
      number: 250,
      category: 'other',
      time: '2018-03-02T10:33:00.000Z'
    },
    {
      id: 6,
      name: 'A',
      family: 'C',
      number: 250,
      category: 'other',
      time: '2018-03-02T10:33:05.000Z'
    }
  ]
]

As you can see, only id and time, are unique, and I want to group it based on duplicatesname, family, number and category, So all objects which have the same value for name, family, number and category should have a separate array.

I have tried a lot of things, I used two nested for loop, I used map, I sued Filter, ... I tried all I could think of, but I was not able to do it!

If anyone can help one this, I really appreciate it.

This is the input array of object:

var array = [{
    id: 1,
    name: 'A',
    family: 'B',
    number: 100,
    category: 'test',
    time: '2018-03-02T10:33:00.000Z'
  },
  {
    id: 2,
    name: 'A',
    family: 'B',
    number: 100,
    category: 'test',
    time: '2018-03-02T10:33:50.000Z'
  },
  {
    id: 3,
    name: 'A',
    family: 'B',
    number: 100,
    category: 'test',
    time: '2018-03-02T10:34:30.000Z'
  },
  {
    id: 4,
    name: 'A',
    family: 'B',
    number: 100,
    category: 'test',
    time: '2018-03-02T10:36:00.000Z'
  },
  {
    id: 5,
    name: 'A',
    family: 'C',
    number: 250,
    category: 'other',
    time: '2018-03-02T10:33:00.000Z'
  },
  {
    id: 6,
    name: 'A',
    family: 'C',
    number: 250,
    category: 'other',
    time: '2018-03-02T10:33:05.000Z'
  }
]

I want to group it like this as output:

var output = [
  [{
      id: 1,
      name: 'A',
      family: 'B',
      number: 100,
      category: 'test',
      time: '2018-03-02T10:33:00.000Z'
    },
    {
      id: 2,
      name: 'A',
      family: 'B',
      number: 100,
      category: 'test',
      time: '2018-03-02T10:33:50.000Z'
    },
    {
      id: 3,
      name: 'A',
      family: 'B',
      number: 100,
      category: 'test',
      time: '2018-03-02T10:34:30.000Z'
    },
    {
      id: 4,
      name: 'A',
      family: 'B',
      number: 100,
      category: 'test',
      time: '2018-03-02T10:36:00.000Z'
    }
  ],
  [{
      id: 5,
      name: 'A',
      family: 'C',
      number: 250,
      category: 'other',
      time: '2018-03-02T10:33:00.000Z'
    },
    {
      id: 6,
      name: 'A',
      family: 'C',
      number: 250,
      category: 'other',
      time: '2018-03-02T10:33:05.000Z'
    }
  ]
]

As you can see, only id and time, are unique, and I want to group it based on duplicatesname, family, number and category, So all objects which have the same value for name, family, number and category should have a separate array.

I have tried a lot of things, I used two nested for loop, I used map, I sued Filter, ... I tried all I could think of, but I was not able to do it!

If anyone can help one this, I really appreciate it.

Share Improve this question edited Jul 22, 2018 at 14:24 Rick 4,1249 gold badges27 silver badges37 bronze badges asked Jul 21, 2018 at 8:18 Emad DehnaviEmad Dehnavi 3,4515 gold badges23 silver badges47 bronze badges 1
  • 1 Show us any code because now this question sounds like "do it for me". – An0num0us Commented Jul 21, 2018 at 8:23
Add a ment  | 

3 Answers 3

Reset to default 4

You could take a Map and collect all items of the same group in an array.

Later get only the values of the map as result.

This is only for one one group category.

var array = [{ id: 1, name: 'A', family: 'B', number: 100, category: 'test', time: '2018-03-02T10:33:00.000Z' }, { id: 2, name: 'A', family: 'B', number: 100, category: 'test', time: '2018-03-02T10:33:50.000Z' }, { id: 3, name: 'A', family: 'B', number: 100, category: 'test', time: '2018-03-02T10:34:30.000Z' }, { id: 4, name: 'A', family: 'B', number: 100, category: 'test', time: '2018-03-02T10:36:00.000Z' }, { id: 5, name: 'A', family: 'C', number: 250, category: 'other', time: '2018-03-02T10:33:00.000Z' }, { id: 6, name: 'A', family: 'C', number: 250, category: 'other', time: '2018-03-02T10:33:05.000Z' }],
    grouped = Array.from(array.reduce((m, o) =>
        m.set(o.category, (m.get(o.category) || []).concat(o)), new Map).values());

console.log(grouped);
.as-console-wrapper { max-height: 100% !important; top: 0; }

For more than one group, you could take a joined key with the values of the actual object of name, family, number and category in a closure for key.

Then map new arrays with close times and bine all arrays to single nested arrays. At the end filter by length.

var array = [{ id: 1, sourceAccount: "A", targetAccount: "B", amount: 100, category: "eating_out", time: "2018-03-02T10:33:00.000Z" }, { id: 2, sourceAccount: "A", targetAccount: "B", amount: 100, category: "eating_out", time: "2018-03-02T10:33:50.000Z" }, { id: 3, sourceAccount: "A", targetAccount: "B", amount: 100, category: "eating_out", time: "2018-03-02T10:34:30.000Z" }, { id: 4, sourceAccount: "A", targetAccount: "B", amount: 100, category: "eating_out", time: "2018-03-02T10:36:00.000Z" }, { id: 5, sourceAccount: "A", targetAccount: "C", amount: 250, category: "other", time: "2018-03-02T10:33:00.000Z" }, { id: 6, sourceAccount: "A", targetAccount: "C", amount: 250, category: "other", time: "2018-03-02T10:33:05.000Z" }],
    groupBy = ['name', 'family', 'number', 'category'],
    result = Array
        .from(
            array
                .reduce((m, o) => (k => m.set(k, (m.get(k) || []).concat(o)))(groupBy.map(k => o[k]).join('|')), new Map)
                .values(),
            o => o.sort((a, b) => a.time.localeCompare(b.time))
        )
        .map(g => g.reduce((r, o, i, a) => {
            if (!i || new Date(o.time).getTime() - new Date(a[i - 1].time).getTime() > 60000) {
                r.push([o]);
            } else {
                r[r.length - 1].push(o);
            }
            return r;
        }, []))
        .reduce((r, a) => r.concat(a), [])
        .filter(a => a.length > 1);

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

Simply make a map using Array.reduce() with a bined key of name, family,number and category. And than you can use Object.values() on that map to get the desired result.

var array =[ { id: 1, name: 'A', family: 'B', number: 100, category: 'test', time: '2018-03-02T10:33:00.000Z' }, { id: 2, name: 'A', family: 'B', number: 100, category: 'test', time: '2018-03-02T10:33:50.000Z' }, { id: 3, name: 'A', family: 'B', number: 100, category: 'test', time: '2018-03-02T10:34:30.000Z' }, { id: 4, name: 'A', family: 'B', number: 100, category: 'test', time: '2018-03-02T10:36:00.000Z' }, { id: 5, name: 'A', family: 'C', number: 250, category: 'other', time: '2018-03-02T10:33:00.000Z' }, { id: 6, name: 'A', family: 'C', number: 250, category: 'other', time: '2018-03-02T10:33:05.000Z' } ];

var result = Object.values(array.reduce((a,curr)=>{
  const {name, family, number, category} = curr;
  const key = `${name}_${family}_${number}_${category}`;
  (a[key] = a[key] || []).push(curr);
  return a;
},{}));

console.log(result);

You can also use Array.reduce() to get that output:

var array = [ { id: 1,
  name: 'A',
  family: 'B',
  number: 100,
  category: 'test',
  time: '2018-03-02T10:33:00.000Z' },
  { id: 2,
  name: 'A',
  family: 'B',
  number: 100,
  category: 'test',
  time: '2018-03-02T10:33:50.000Z' },
  { id: 3,
  name: 'A',
  family: 'B',
  number: 100,
  category: 'test',
  time: '2018-03-02T10:34:30.000Z' },
  { id: 4,
  name: 'A',
  family: 'B',
  number: 100,
  category: 'test',
  time: '2018-03-02T10:36:00.000Z' },
  { id: 5,
  name: 'A',
  family: 'C',
  number: 250,
  category: 'other',
  time: '2018-03-02T10:33:00.000Z' },
  { id: 6,
  name: 'A',
  family: 'C',
  number: 250,
  category: 'other',
  time: '2018-03-02T10:33:05.000Z' } 

];

var res = array.reduce((acc, obj)=>{
  var existObj;
  for(var i = 0 ; i < acc.length; i++) {
    let accArray = acc[i];
    if(accArray){
     existObj = accArray.find(({name, family, number, category}) =>  name == obj.name && family == obj.family && number == obj.number && category == obj.category);
     if(existObj) {
        accArray.push(obj);
        return acc;
     }
    }
 }
  acc.push([obj]);
  return acc;
}, []);
console.log(res);

发布评论

评论列表(0)

  1. 暂无评论