I have an array of objects and I want to create a sequence based on each value. For example take the array:
let starting_data = [
{str: "a"},
{str: "a"},
{str: "b"},
{str: "c"},
{str: "a"},
{str: "c"},
{str: "a"},
{str: "b"}
]
I know I can use a map and reduce to find the unique number of each str value
let uniques = starting_data.map(function(value) {return value.str;}).reduce((acc, val) => {
acc[val] = acc[val] === undefined ? 1 : acc[val] += 1;
return acc;
}, {})
But I'm not sure how to leverage this to eventually get what I want as my desired output:
let desired_output = [
{str: "a", count: 1},
{str: "a", count: 2},
{str: "b", count: 1},
{str: "c", count: 1},
{str: "a", count: 3},
{str: "c", count: 2},
{str: "a", count: 4},
{str: "b", count: 2}
]
Where the counts start over for each unique value, but the as go to 4, and b and c go to 2. I tried messing with arr.sort if I need to do that first but I wasn't sure how to sort based on a value inside an object... Any help appreciated!!
can do something like keeping a seperate object to keep track of the counts
let starting_data = [
{str: "a"},
{str: "a"},
{str: "b"},
{str: "c"},
{str: "a"},
{str: "c"},
{str: "a"},
{str: "b"}
]
let counts = {};
let res = starting_data.map(({str}) => {
if(!counts[str])counts[str]=0;
counts[str]+=1
return {str,count:counts[str]}
})
console.log(res)
You mentioned it you want it to be purely functional, so here it is.
let starting_data = [
{ str: "a" },
{ str: "a" },
{ str: "b" },
{ str: "c" },
{ str: "a" },
{ str: "c" },
{ str: "a" },
{ str: "b" },
];
const uniqueCount = starting_data
.reduce(
(arr, { str }) => {
const hash = arr[0];
hash[str] ||= 0;
arr.push({ str, count: ++hash[str] });
return arr;
},
[{}]
)
.slice(1);
console.log(uniqueCount);
This prints:
[
{ str: 'a', count: 1 },
{ str: 'a', count: 2 },
{ str: 'b', count: 1 },
{ str: 'c', count: 1 },
{ str: 'a', count: 3 },
{ str: 'c', count: 2 },
{ str: 'a', count: 4 },
{ str: 'b', count: 2 }
]
This solution keeps a hash as the first element of the array being built by reduce.
[{}].0 if the key doesn't already exist.str and a count.hash[str] is incremented by 1 and then used as the value.The array now looks like:
[{ a: 1 }, { str: "a", count: 1 }]
[ { a: 2 }, { str: 'a', count: 1 }, { str: 'a', count: 2 } ]
[ { a: 2, b: 1 }, { str: 'a', count: 1 }, { str: 'a', count: 2 }, { str: 'b', count: 1 } ]
// Continues until it finishes
Hope this helps.