Lodash - Find deep in array of object

孤街浪徒 提交于 2019-12-30 17:42:10

问题


I have an array of an object like this

[
    {
        '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
            }
        ]
    },
]

What I need is sum the property Val when prop is foo. So, I have to search through elements and get all objects where prop is foo. With this objects, I should sum the val property.

I tried to use many combinations of _.find, _.pick and so on, but I don't get the right result. Can someone help me?


回答1:


Here's a solution that flattens the elements and then filters the result to get the required elements before summing the 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()

Chaining is a way of applying a sequence of operations to some data before returning a value. The above example uses explicit chaining but could be (maybe should be) written using implicit chaining:

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



回答2:


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

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

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

Then use 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 sum:

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



回答3:


You can use _.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




回答4:


You can loop through the data and get the sum.Try this:

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 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);



回答5:


Here's a one liner 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, "c.d", "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"}}


来源:https://stackoverflow.com/questions/41610948/lodash-find-deep-in-array-of-object

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!