簡體   English   中英

Lodash - 在對象數組中深入查找

[英]Lodash - Find deep in array of object

我有一個像這樣的對象數組

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

我需要的是當propfoo時對屬性Val求和。 因此,我必須搜索元素並獲取propfoo所有對象。 有了這個對象,我應該總結val屬性。

我嘗試使用_.find_.pick等的多種組合,但沒有得到正確的結果。 有人能幫我嗎?

這是一個將元素展,然后在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;
});

這是針對此問題的單行解決方案:

 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"}}

披露:我是那個圖書館的作者


您可以使用deepdash 中的 _.eachDeep方法:

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

這是您的案例的示例

您可以遍歷數據並獲得總和。試試這個:

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

使用過濾器:

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

如果有人需要,這里有對我有用的解決方案。 但我的情況有點不同,我需要找到一個與 id 匹配的數組。

這里有一個流函數,它並不是真正意義上的,但它確實使代碼更易於閱讀

const flow = functions => data =>
    functions.reduce((value, func) => func(value), data);

   const 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
                }
            ]
        },
    ]

    const result= _.flow([
        data => _.map(data, 'elements'), // get all elements from the array 
        data => _.flatten(data), // create a singler array 
        data => _.find(data, { val: 65 }) // find the needed value in array 
        // you can keep on adding logic here depending on your need
    ])(arr); // the inital array 
    

如果您不想使用流功能,也可以這樣做,我想我沒有測試代碼,但它應該可以工作

const results = _.find(_.flatten(_.map(arr, 'elements')), { val: 65 });

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM