首页 > 解决方案 > 如何使用 lodash 在嵌套的对象数组中查找对象?

问题描述

我有这个数据集

var records = [{
    gc: '2',
    time: 1231232423,
    cards: [{
        cardCode: '12121',
        rssi: 23
      }, {
        cardCode: '12122',
        rssi: 33
      }, {
        cardCode: '12421',
        rssi: 43
      }

    ]
  },
  {
    gc: '3',
    time: 4331232233,
    cards: [{
        cardCode: '6423',
        rssi: 23
      }, {
        cardCode: '12421',
        rssi: 13
      }

    ]
  }, , {
    gc: '4',
    time: 4331232233,
    cards: [{
        cardCode: '8524',
        rssi: 03
      },
      {
        cardCode: '6423',
        rssi: 23
      }, {
        cardCode: '12421',
        rssi: 67
      }
    ]
  }
]

我有一个(records)对象数组,每个对象都有另一个数组(cards)。这意味着如果我将始终cards在“记录”中存在的对象内有数组。所以从一开始我想遍历整个列表records并将所有对象的卡片数组相互比较,然后找到匹配对象的rssi值并将对象(具有最小 rssi 值)推送到另一个新数组中。最后以同样的方式,我想要一个数组,其中包含所有具有最小 rssi 值的匹配对象。我正在使用lodash并尝试过这个

 matchedRecords =   records.forEach(record=>{
 record.cards.forEach(record=>{
  _.filter(records, _.flow(
    _.property('cards'),
     _.partialRight(_.some, { cardCode: record.cardCode })
         ));
      })
   })

我想要的结果是

 [
   {
    gc : 3, 
    cards : [{
     cardCode : '12421',
     rssi : 13
    }]
   }
 ]

注意:卡片数组对象应该在基础上进行比较cardCode key

标签: javascriptlodash

解决方案


更新

这个版本是基于对问题的评论中长时间的需求讨论后达成的理解。它不使用 lodash。它已经变得足够复杂,它可能应该分成更小的部分,而 lodash 可能会对此有所帮助。

它不仅包括原始记录,gctime包括原始记录,实际上,还将包括那里的任何其他内容。如果您只想要gc,只需...rest从代码中删除。

const sharedCards = records => 
  Object.values(
    Object .entries (records .reduce (
      (a, {cards, ...rest}) => cards .reduce (
        (a, {cardCode, rssi}) => ({
          ...a, 
          [cardCode]: [...(a[cardCode] || []), {...rest, rssi}]
        }),
        a,
      ), 
      {}
    ))
    .filter ( ([code, rs]) => rs.length == records.length )
    .reduce((a, [code, rs]) => {
      const {gc, rssi, ...rest} = rs.reduce(
        (r1, r2) => r2.rssi < r1.rssi ?  r2 : r1, 
        {rssi: Infinity}
      )
      return {
        ...a, 
        [gc]: {
          ...(a[gc] || {...rest, gc}), 
          cards: [...((a[gc] || {gc}).cards || []), {cardCode: code, rssi}]
        }
      }
    }, {})  
  )
  
  
const records = [{gc: "2", time: 1231232423, cards: [{cardCode: "12121", rssi: 23}, {cardCode: "12122", rssi:33}, {cardCode: "12421", rssi: 43}]}, {gc: "3", time: 4331232233, cards: [{cardCode: "6423", rssi: 23}, {cardCode: "12421", rssi: 13}]}, {gc: "4", time: 4331232233, cards: [{cardCode: "8524", rssi: 3}, {cardCode: "6423", rssi: 23}, {cardCode: "12421", rssi: 67}]}];

console .log (
  sharedCards (records)
)

// Now we add `{cardCode: "6423", rssi: 7}` to the first record
const records2 = [{gc: "2", time: 1231232423, cards: [{cardCode: "6423", rssi: 7}, {cardCode: "12121", rssi: 23}, {cardCode: "12122", rssi:33}, {cardCode: "12421", rssi: 43}]}, {gc: "3", time: 4331232233, cards: [{cardCode: "6423", rssi: 23}, {cardCode: "12421", rssi: 13}]}, {gc: "4", time: 4331232233, cards: [{cardCode: "8524", rssi: 3}, {cardCode: "6423", rssi: 23}, {cardCode: "12421", rssi: 67}]}];

console .log (
  sharedCards (records2)
)

原始答案

这只是部分解决方案,如果我们可以解决评论中的讨论,将进行更新。它获取每条记录中出现的所有卡片,并选择具有最低 rssi 的版本。这可能接近要求,也可能不符合要求。

它不使用 lodash。使用 lodash 可能会简化一点,但可能不会简化很多。

const sharedCards = records => 
  Object .entries (records .reduce (
    (a, {cards}) => cards .reduce (
      (a, {cardCode, rssi}) => ({...a, [cardCode]: [...(a[cardCode] || []), rssi]}),
      a,
    ), 
    {}
  ))
  .filter ( ([code, rssis]) => rssis.length == records.length )
  .map ( ([code, rssis]) => ({ cardCode: code, rssi: Math .min (...rssis) }) )
    

const records = [{gc: "2", time: 1231232423, cards: [{cardCode: "12121", rssi: 23}, {cardCode: "12122", rssi:33}, {cardCode: "12421", rssi: 43}]}, {gc: "3", time: 4331232233, cards: [{cardCode: "6423", rssi: 23}, {cardCode: "12421", rssi: 13}]}, {gc: "4", time: 4331232233, cards: [{cardCode: "8524", rssi: 3}, {cardCode: "6423", rssi: 23}, {cardCode: "12421", rssi: 67}]}];

console .log (
  sharedCards (records)
)

// Now we add `{cardCode: "6423", rssi: 7}` to the first record
const records2 = [{gc: "2", time: 1231232423, cards: [{cardCode: "6423", rssi: 7}, {cardCode: "12121", rssi: 23}, {cardCode: "12122", rssi:33}, {cardCode: "12421", rssi: 43}]}, {gc: "3", time: 4331232233, cards: [{cardCode: "6423", rssi: 23}, {cardCode: "12421", rssi: 13}]}, {gc: "4", time: 4331232233, cards: [{cardCode: "8524", rssi: 3}, {cardCode: "6423", rssi: 23}, {cardCode: "12421", rssi: 67}]}];

console .log (
  sharedCards (records2)
)


推荐阅读