【问题标题】:ES6 - Finding data in nested arraysES6 - 在嵌套数组中查找数据
【发布时间】:2017-02-22 20:32:50
【问题描述】:

在使用 findfilter 的 ES6 中,我很乐意使用值进行迭代以在数组中查找元素。

但是,我正在尝试根据嵌套数组中的值从父数组中获取值。

例如,在这个数据结构中:

products: [
  {
    id: 01,
    items: [
      {
        id: 01,
        name: 'apple'
      },
      {
        id: 02,
        name: 'banana'
      },
      {
        id: 03,
        name: 'orange'
      }
    ]
  },
  {
    id: 02,
    items: [
      {
        id: 01,
        name: 'carrot'
      },
      {
        id: 02,
        name: 'lettuce'
      },
      {
        id: 03,
        name: 'peas'
      }
    ]
  },
  {
    id: 03,
    items: [
      {
        id: 01,
        name: 'eggs'
      },
      {
        id: 02,
        name: 'bread'
      },
      {
        id: 03,
        name: 'milk'
      }
    ]
  }
]

如果我知道对象milknameid,有没有办法找出它嵌套在其中的元素的ID?

目前我有这个:

products.find((product) => {
  product.find((prod) => {
    return prod.name === 'milk';
  });
});

只返回包含milk的对象。

【问题讨论】:

    标签: javascript arrays ecmascript-6


    【解决方案1】:

    直接获取item,不加倍返回获取名称:

    let found;
    for ( const category of products ){
        found = category.items.find( item => item.name == "milk" )
        if ( found ) break
    }
    found // == { id: 3, name: 'milk' }
    

    【讨论】:

      【解决方案2】:

      我知道你提到了 ES6,但在这种情况下(如果你想返回内部对象)我相信最好使用 for/of 而不是 map/reduce/find

      for (let p of products) {
        for (let i of p.items) {
          if (i.name === 'milk') return i;
        }
      }
      

      【讨论】:

        【解决方案3】:

        接受的答案对我没有用,因为我想要内部查找的结果,同时使用它总是给我外部过滤器/查找的结果,我不得不使用结果数组来查找值再次。

        所以我改为使用 reduce 和短路来获得内部结果。

        // undefined as the initial value is necessary, otherwise it gets the first value of the array instead.
        
        return products.reduce((prev, product) => prev || product.items.find(item => item.name === 'milk'), undefined);
        

        const products = [
          {id: 1, items: [
            {id: 1, name: 'apple'},
            {id: 2, name: 'banana'},
            {id: 3, name: 'orange'}
          ]},
          {id: 2, items: [
            {id: 1, name: 'carrot'},
            {id: 2, name: 'lettuce'},
            {id: 3, name: 'peas'}
          ]},
          {id: 3, items: [
            {id: 1, name: 'eggs'},
            {id: 2, name: 'bread'},
            {id: 3, name: 'milk'}
          ]}
        ];
        
        console.log(products.reduce((prev, product) => prev || product.items.find(item => item.name === 'milk'), undefined));

        【讨论】:

        • 谢谢,古斯塔沃!一直在网上搜索解决方案以获取内部发现。你太棒了!
        • 请注意,即使在找到一个项目后,这种方式仍会继续搜索该项目。 reduce 函数不能中断。 @ariel 的解决方案确实会在发现时中断。
        【解决方案4】:

        你必须从外部find 的回调中返回一些东西。事实上,对于内部迭代,您不应该使用find,而应该使用some,它返回一个布尔值,用于判断数组中是否存在与条件匹配的元素:

        products.find((product) => {
          return product.items.some((item) => {
        //^^^^^^
            return item.name === 'milk';
          });
        });
        

        或者简而言之:

        products.find(product => product.items.some(item => item.name === 'milk'));
        

        然后检查find是否找到了东西(不是null!)并得到它的.id,结果应该是03。或者,您可以 filter 为包含牛奶作为商品的产品,然后将所有结果映射到它们的 id:

        products.filter(product =>
          product.items.some(item => item.name === 'milk');
        ).map(product =>
          product.id
        ) // [03]
        

        【讨论】:

        • 这是有道理的——我以前没见过some.. 但是使用这个,我将如何返回外部元素的 id?例如,对于项目milk,包含元素的id 为3。谢谢!
        • 请注意,some 应该出现在 product.items,而不是直接出现在 product
        • @Toby Bergi 给你的代码会找到你的对象,你所要做的就是打电话给.idconst yourId = products.find(product => product.items.some(item => item.name === 'milk')).id
        • 如果我想获取数组索引怎么办?
        • @Kakajann 只需使用findIndex 而不是find
        猜你喜欢
        • 2013-06-17
        • 2022-01-18
        • 2018-03-01
        • 1970-01-01
        • 2019-08-15
        • 2022-11-11
        • 2016-10-03
        • 2013-03-09
        • 2015-05-18
        相关资源
        最近更新 更多