5

Take for example this array:

 [{id: 0, weight: 200}
 {id: 0, weight: 200}
 {id: 1, weight: 75}
 {id: 2, weight: 5}]

I need to get it a result of :

[  {id:0, times:2},
   {id:1, times:1},
   {id:2, times:1}]
6
  • can you show the code where you have attempted a solution? Commented Jul 12, 2017 at 17:27
  • Is there a limited range of what the id's could be? Commented Jul 12, 2017 at 17:27
  • 1
    Possible duplicate of Combine multiple arrays by same key Commented Jul 12, 2017 at 17:32
  • @Kadima nope the ids can be random Commented Jul 12, 2017 at 17:34
  • @NateAnderson I deleted the code already but what I tried to do was to iterate each item of the array through the same array and compare ids and push a result object into a results array. Commented Jul 12, 2017 at 17:37

3 Answers 3

9

You could reduce the array into a new array with the count

var arr = [
    { id: 0, weight: 200 }, 
    { id: 0, weight: 200 }, 
    { id: 2, weight: 75  }, 
    { id: 9, weight: 5   }
];

var arr2 = arr.reduce( (a,b) => {
    var i = a.findIndex( x => x.id === b.id);
    return i === -1 ? a.push({ id : b.id, times : 1 }) : a[i].times++, a;
}, []);

console.log(arr2)

Sign up to request clarification or add additional context in comments.

5 Comments

Why the comma operator?
It's a return statement, so it returns anything after the last comma.
i know. But why not n?n:n; return a; <= the same but easuer to understand
Says the guy who sticks an IIFE in the middle of his code to create an unnecessary closure? Anyway, it's just a habit, could just as easily have done the assigning before the return in this case.
@adaneo touché.
2

This simple reducer will return an array of arrays, each one containing all the duplicate elements in the original array.

function groupDuplicates(array, compareF) {
    return array.reduce((acc, item) => {
        const existingGroup = acc.find(g => (compareF(g[0], item)));
        if (existingGroup) {
            existingGroup.push(item);
        } else {
            acc.push([item])
        }
        return acc;
    }, []);
}

Where compareF is your custom comparator, and should returns true if it's parameters are considered to be equal.

NOTE: In this implementation, non duplicated items will remain as the only element in their array. You may want to filter these out later, like so:

const duplicatesOnly = groupDuplicates(myArray, myComparator).filter(i => (i.length > 1));

Comments

1
var array= [
 {id: 0, weight: 200},
 {id: 0, weight: 200},
 {id: 1, weight: 75},
 {id: 2, weight: 5}];

console.log(array.reduce((function(hash){
return function(array,obj){
 if(!hash[obj.id])
  array.push(hash[obj.id]={id:obj.id,times:1});
 else
   hash[obj.id].times++;
  return array;
  };    
})({}),[]));

See Combine multiple arrays by same key for an explanation and you can try it here :http://jsbin.com/licuwadifa/edit?console.

3 Comments

No reason to repost your answer when you already voted to close as a duplicate.
@bergi its not an exact duplicate and i thought the OP might not be able to implement it for his usecase.
@Jonasw yup i did see the post that you linked to before but i didnt know how to implement it. Thank you so much!! You're a real lifesaver:)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.