1

Using javascript functional programming methods (like map/reduce), how would one aggregate/count the status field of arr1 and transform it to an array of key/value objects in arr2.

arr1 = [
  {'task':'do something 1', 'status':'done'} , 
  {'task':'do something 2', 'status':'done'} , 
  {'task':'do something 3', 'status':'pending'} , 
  {'task':'do something 4', 'status':'done'}
];

// Aggregate arr1 `status` field and transform to:

arr2 = [
  {key:'done', value: 3},
  {key:'pending', value: 1}
];

Here's my WIP partial solution that handles only the aggregation portion. I still need the transform portion.

var arr2 = arr1.map(function(item) {
    return item.status;
  }).reduce(function(acc,curr,idx){
    if(acc[curr] === undefined) acc[curr] = 1;
    else acc[curr] += 1;
    return acc;
  }, []); 
6
  • 1
    I'd just do this, but not sure it's "functional" enough. Commented Feb 3, 2016 at 4:35
  • Your solution doesn't give the expected answer. Or the provided answer is incorrect. Commented Feb 3, 2016 at 4:38
  • I believe @Kiril is right, the posted code produces [done: 3, pending: 1], or in other words it treats an array as an object, and doesn't return the expected result ? Commented Feb 3, 2016 at 4:42
  • @adeneo, your solution is great. Why not post it as an answer? Commented Feb 3, 2016 at 4:57
  • @jboothe - wasn't really sure that's what you wanted, but I'll post if for posterity Commented Feb 3, 2016 at 5:20

4 Answers 4

1

Here's the most functional way I could come up with. This includes both the aggregation and your desired transform:

var arr2 = Object.keys(arr2 = arr1.map(function(item) {
    return item.status;
}).reduce(function(acc,curr){
    acc[curr] = acc[curr] + 1 || 1;
    return acc;
}, [])).map(function(item){
    return {key: item, value: arr2[item]}
});
Sign up to request clarification or add additional context in comments.

3 Comments

Alex, very nicely done. The only cleanup I'd make is to my own code - consolidate lines 4 & 5 into a ternary acc[curr] === undefined ? acc[curr] = 1 : acc[curr] + 1;
@jboothe good point! I was also thinking ternary but came up with a slightly more compact solution, what do you think?
Nifty. undefined + 1 or 1.
0

You can try Array.prototype.forEach(). Also instead of using an array, you can use object. This will save you looping over to find count of a specific status.

arr1 = [
  {'task':'do something 1', 'status':'done'} , 
  {'task':'do something 2', 'status':'done'} , 
  {'task':'do something 3', 'status':'pending'} , 
  {'task':'do something 4', 'status':'done'}
];

var result = {};
arr1.forEach(function(item){
  if(!result[item.status])
    result[item.status] = 0;
  
  result[item.status]++;
});
console.log(result);

Comments

0

Since you are storing the output value as an array you should check weather the key status is present or not. If present increment its value.

arr2 = [];
arr1.forEach(function(item){
  var keyPresent = false;
  for(var i = 0, len = arr2.length; i < len; i++) {
      if( arr2[ i ].key === item.status ){
         keyPresent = true;
         arr2[ i ].value++
      }
  }
  if(!keyPresent){
    arr2.push({key: item.status , value : 1})
}

The output given by

arr2 = [
  {key:'done', value: 3},
  {key:'pending', value: 1}
];

Comments

0
const arr_done = arr1.filter(item => item.status == 'done');
const arr_pending = arr1.filter(item => item.status === 'pending');
arr2 = [
   {key:'done', value: arr_done.length}, 
   {key:'pending', value: arr_pending.length}
];
console.log(arr2);

1 Comment

Please read How do I write a good answer?. While this code block may answer the OP's question, this answer would be much more useful if you explain how this code is different from the code in the question, what you've changed, why you've changed it and why that solves the problem without introducing others. - From Review

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.