Lodash-найти глубоко в массиве объекта

у меня есть массив объектов, как это

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

что мне нужно-это сумма имущества Val, когда prop и foo. Итак, я должен искать через элементы и получить все объекты, где prop и foo. С помощью этих объектов я должен суммировать val собственность.

Я пытался использовать много комбинаций _.find, _.pick и так далее, но я не получаю правильного результата. Кто-нибудь может мне помочь?

3 ответов


вот решение, которое плющит элементы, а потом фильтры результат, чтобы получить необходимые элементы до резюме свойство val:

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

цепочка-это способ применения последовательности операций к некоторым данным перед возвращением значения. В приведенном выше примере используется явная цепочка, но может быть (возможно, должна быть) написана с использованием неявной цепочки:

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

Я создал библиотеку, которую вы можете использовать:https://github.com/dominik791/obj-traverse

findAll() метод должен решить вашу проблему. Первый параметр является корневым объектом, а не массивом, поэтому сначала вы должны создать его:

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

затем использовать findAll() способ:

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

matchingObjects переменная хранит все объекты с prop равна foo. И в конце рассчитайте свою сумму:

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

вы можете перебирать данные и получать сумму.Попробуйте это:

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

С ПОМОЩЬЮ 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);