1

I was looking for a way to group an array of object by a field.

I found a very useful answer in the comments of this answer (by @tomitrescak : https://stackoverflow.com/a/34890276/7652464

function groupByArray(xs, key) { 
return xs.reduce(function (rv, x) { 
    let v = key instanceof Function ? key(x) : x[key]; 
    let el = rv.find((r) => r && r.key === v); 
    if (el) { 
        el.values.push(x); 
    } 
    else { 
        rv.push({ key: v, values: [x] }); 
    } 
    return rv; }, []);

}

Which can be used as following

console.log(groupByArray(myArray, 'type'); 

This function works perfect, however, my array contains objects with embedded fields.

I would like to use the the function as following

console.log(groupByArray(myArray, 'fullmessage.something.somethingelse');

I already have a function for extracting the embedded fields which works.

function fetchFromObject(obj, prop) {

if(typeof obj === 'undefined') {
    return '';
}

var _index = prop.indexOf('.')
if(_index > -1) {
    return fetchFromObject(obj[prop.substring(0, _index)], prop.substr(_index + 1));
}

return obj[prop];

}

Which can be used as following

var obj = { obj2 = { var1 = 2, var2 = 2}};

console.log(fetchFromObject(obj, 'obj2.var2')); //2

Can somebody help my to implement my function into the the group function.

Jan
  • 560
  • 6
  • 19

2 Answers2

1

You could change the line

let v = key instanceof Function ? key(x) : x[key];

into

let v = key instanceof Function ? key(x) : fetchFromObject(x, key);

for getting a value of an arbitrary nested key.

Nina Scholz
  • 376,160
  • 25
  • 347
  • 392
  • 1
    Oh I'm sorry that did work. Thank you! I had a little mistake regarding the field name. – Jan Jun 27 '17 at 12:24
  • Well, no. This `groupBy` already supports function arguments, all you have to do is to pass a closure `x => fetchFromObject(x, 'fullmessage.etc')` as a `key` – georg Jun 27 '17 at 12:28
  • @georg, that would be necessary for any of the nestes objects. – Nina Scholz Jun 27 '17 at 12:33
0
function groupBy(arr,props){
 var props=props.split(".");
 var result=[];
 main:for(var i=0;i<arr.length;i++){
  var value=arr[i];
  for(var j=0;j<props.length;j++){
    value=value[props[j]];
    if(!value) continue main;
  }
  result.push(value);
 }
return result;
}

Usecase:

groupBy({a:{b:2}},{a:{b:undefined}},{a:{b:3}},"a.b")//returns [2,3]
Jonas Wilms
  • 132,000
  • 20
  • 149
  • 151