-2

I have an array like [{type: car}, {type: van}, {type: truck}, {type: car}]

I need to return an array that looks like: [{type: car, count: 1}, {type: van, count: 1}, {type: truck, count: 1}, {type: car, count: 2}]

in the returned array, there is a new prop that stores what number of instance that value for type is. i.e. how many times has this value shown up in the array.

This is for an array that will be rendered and I want to include a number next to values that have duplicates in the array. I'm working with array methods reduce and map, maybe I will need a find function, I'm not sure

The main diff from the link for the possible duplicate and my question is that the linked question/answer results in an array with each unique value and a count of the duplicates whereas I would like my og array with an additional prop that is the number of times this value has shown up in the array. so the first instance of a value would be have count: 1, the second instance count: 2 and so on.

I've tried using a reduce function to give me a count of the duplicates for each value but now that I'm mapping through the original array I'm having trouble determining if i'm on the first, second, ect of that value. for example I can find if there are 3 of the current value i'm on in my array.map but I don't know if its the first or second or third one in that array.

here is what I have:

let countArray = this.props.clauses.reduce((prev, cur) => {prev[cur.leaseClauseType] = (prev[cur.leaseClauseType] || 0) + 1; return prev; }, {});

this.props.clauses.map((c: AnyObject, index: number)=> {
//Here i can append the count from countArray to each value but I'd like to know if its the first, second ect. of that value
}
Chris P
  • 96
  • 10
  • 5
    And what have you tried so far? – ASDFGerte Oct 21 '19 at 16:12
  • 2
    Possible duplicate of [Group and count values in an array](https://stackoverflow.com/questions/44387647/group-and-count-values-in-an-array) – JR Kincaid Oct 21 '19 at 16:18
  • So far, I have a reduce function that shows me how many of each unique value in the array i have: `let countArray = this.props.clauses.reduce((prev, cur) => {prev[cur.leaseClauseType] = (prev[cur.leaseClauseType] || 0) + 1; return prev; }, {});` which is great but now as i map through the og array, if i find the count for the current value i'm on in the map, I still don't know if i'm on the first instance or second ect. – Chris P Oct 21 '19 at 16:26
  • Also, thanks for the link but I don't think this is a duplicate of that questions. I want to have the full array, duplicates and all, with an additional property stating what number of duplicate the value is. so, all unique values would have 1 in the count property but on the second and third and so on instance of any value, I'd like to have a number for the number of times that value has shown up. I'm sorry if my explanation is confusing, I'm having a very difficult time articulating my question. – Chris P Oct 21 '19 at 16:30
  • If there is a reason this is being downvoted let me know. I've never done this type of array manipulation before and couldn't find any articles or questions on stackoverflow that addressed my question. – Chris P Oct 21 '19 at 16:38
  • 1
    in your reduce callback, you know the ith dupplicate count. Just store it on the cur object. (If you can't store on props, just store on an array samely indexed as props) – grodzi Oct 21 '19 at 16:50

2 Answers2

1

This can be quickly done using two loops:

const addCountProp = function (arr) {
  // to store number of instances for each type
  const typeMap = {};
  
  for (let i = 0; i < arr.length; i++) {
    const elem = arr[i];
    
    if (typeMap[elem.type] === undefined)
      typeMap[elem.type] = 0;
    
    typeMap[elem.type] += 1;
  }
  
  // add 'count' property to each element of the array
  for (let i = 0; i < arr.length; i++) {
    const elem = arr[i];
    elem.count = typeMap[elem.type];
  }
  
  return arr;
};
mahdavipanah
  • 600
  • 5
  • 21
1

You could take a Map for counting

var data = [{ type: 'car' }, { type: 'van' }, { type: 'truck' }, { type: 'car' }],
    result = Array.from(
        data.reduce((m, { type }) => m.set(type, (m.get(type) || 0) + 1), new Map),
        ([type, count]) => ({ type, count })
    );

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Nina Scholz
  • 376,160
  • 25
  • 347
  • 392