Lodash - Find an array of an array of objects

I have an array of this type

[ { 'a': 10, elements: [ { 'prop': 'foo', 'val': 10 }, { 'prop': 'bar', 'val': 25 }, { 'prop': 'test', 'val': 51 } ] }, { 'b': 50, elements: [ { 'prop': 'foo', 'val': 30 }, { 'prop': 'bar', 'val': 15 }, { 'prop': 'test', 'val': 60 } ] }, ] 

I need to summarize the Val property when prop is equal to foo . So, I have to look for elements and get all the objects where prop is foo . With these objects, I have to summarize the Val property.

I tried using many combinations of _.find , _.pick , etc., but I am not getting the correct result. Can anybody help me?

+7
source share
5 answers

Here's a solution that aligns the elements and then filters to get the required elements before the summing val property:

 var result = _.chain(data) .map('elements') // pluck all elements from data .flatten() // flatten the elements into a single array .filter({prop: 'foo'}) // exatract elements with a prop of 'foo' .sumBy('val') // sum all the val properties .value() 

A chain is a way of applying a sequence of operations to some data before returning a value. The above example uses an explicit chain, but can (possibly should) be written using an implicit chain:

 var result = _(data) .map('elements') .flatten() .filter({prop: 'foo'}) .sumBy('val'); 
+14
source

I created a library that you can use: https://github.com/dominik791/obj-traverse

findAll() method should solve your problem. The first parameter is the root object, not the array, so you must first create it:

 var rootObj = { name: 'rootObject', elements: [ { 'a': 10, elements: [ ... ] }, { 'b': 50, elements: [ ... ] } ] }; 

Then use the findAll() method:

 var matchingObjects = findAll( rootObj, 'elements', { 'prop': 'foo' } ); 

matchingObjects variable stores all objects with prop equal to foo . And at the end, calculate your amount:

 var sum = 0; matchingObjects.forEach(function(obj) { sum += obj.val; }); 
+4
source

You can use the _.eachDeep method from deepdash:

 let sum = 0; _.eachDeep(obj, (value, key, parent) => { sum += (key == 'prop' && value == 'foo' && parent.val) || 0; }); 

here is an example for your case

+1
source

You can view the data and get the amount. Try the following:

 var arr=[ { 'a': 10, elements: [ { 'prop': 'foo', 'val': 10 }, { 'prop': 'bar', 'val': 25 }, { 'prop': 'test', 'val': 51 } ] }, { 'b': 50, elements: [ { 'prop': 'foo', 'val': 30 }, { 'prop': 'bar', 'val': 15 }, { 'prop': 'test', 'val': 60 } ] } ]; var sum=0; for(x in arr){ for(i in arr[x]['elements']){ if(arr[x]['elements'][i]['prop'] == 'foo'){ sum=sum+arr[x]['elements'][i]['val']; } } } console.log(sum); 

USING THE FILTER:

 var arr=[ { 'a': 10, elements: [ { 'prop': 'foo', 'val': 10 }, { 'prop': 'bar', 'val': 25 }, { 'prop': 'test', 'val': 51 } ] }, { 'b': 50, elements: [ { 'prop': 'foo', 'val': 30 }, { 'prop': 'bar', 'val': 15 }, { 'prop': 'test', 'val': 60 } ] } ]; var sum=0; arr.filter(function (person) { person['elements'].filter(function(data){ if (data.prop == "foo"){ sum=sum+data.val; } }); }); console.log(sum); 
0
source

Here is one solution to this problem:

 const _ = require('lodash') let deepFind = (JSONArray, keyPath, keyValue) => _.find(JSONArray, _.matchesProperty(keyPath, keyValue)) let JSONArray = [{a:1, b:2, c:{d: "cd"}}, {a:3, b:4, c:{d: "ef"}}, {a:3, b:4, c:[{d: "ef"}]} ] console.log(deepFind(JSONArray, "cd", "cd")) // {a:1, b:2, c:{d: "cd"}} console.log(deepFind(JSONArray, "b", 4)) //{a:3, b:4, c:{d: "ef"}} console.log(deepFind(JSONArray, ['c', 'd'], "cd")) //{a:1, b:2, c:{d: "cd"}} console.log(deepFind(JSONArray, 'c[0].d' /* OR ['c', '0', 'd']*/, "ef")) //{a:1, b:2, c:{d: "cd"}} 
0
source

Source: https://habr.com/ru/post/1262689/


All Articles