简体   繁体   English

递归过滤对象数组

[英]Filtering Array of Objects Recursively

I have these data structure 我有这些数据结构

products:[
      {
        products_number: 14,
        products_ID: 'lvs_jeans-man',
        products_seller: 'a',
        products_SKU: [
          {
            productSKU_ID: 'nfl_lvs_jeans-man_xl_bl-stripe',
            productSKU_size: 'XL',
            productSKU_color: 'Blue_White'
          },
          {
            productSKU_ID: 'nfl_lvs_jeans-man_xl_bk',
            productSKU_size: 'XL',
            productSKU_color: 'Black'
          }
        ]
      },
      {
      products_number: 15,
      products_ID: 'lvs_jeans-man',
      products_seller: 'b',
      products_SKU: [
        {
          productSKU_ID: 'nfl_lvs_jeans-man_xl_bk',
          productSKU_size: 'XL',
          productSKU_color: 'Black'
        }
      ]
    },
    {
      products_number: 16,
      products_ID: 'lvs_jeans-man',
      products_seller: 'c',
      products_SKU: [
        {
          productSKU_ID: 'nfl_lvs_jeans-man_xl_gy',
          productSKU_size: 'XL',
          productSKU_color: 'Grey',

        }
      ]
    }
  ]

The constant 常数

  var id = 'lvs_jeans-man'
  var size = 'XL'
  var color = 'Black'

How do i filter items that met these condition 如何过滤满足这些条件的项目

products_ID == id
productSKU_color == color
productSKU_size == size

The needed output is 所需的输出是

  [{
    products_number: 14,
    products_ID: 'lvs_jeans-man',
    products_seller: 'a',
    productSKU_ID: 'nfl_lvs_jeans-man_xl_bk',
  },
  {
    products_number: 15,
    products_ID: 'lvs_jeans-man',
    products_seller: 'b',
    productSKU_ID: 'nfl_lvs_jeans-man_xl_bk',
  }]

What i have tried is filter the products_ID first then filter the color and size so i can get the productSKU_ID inside and then just play around with array push, but it return Cannot read property 'filter' of undefined" 我尝试过的是先过滤products_ID,然后过滤颜色和大小,以便我可以在其中获取productSKU_ID,然后随便进行数组推送,但返回Cannot read property 'filter' of undefined"

var temp1 =  this.products.filter((product => product.products_ID === this.id).products_SKU.filter(sku => (sku.productSKU_color === this.color && sku.productSKU_size === this.size)))

How to achieve the needed output? 如何实现所需的输出?

The function filter is not suitable because you need to build a custom output with data from the array .products_SKU . 函数过滤器不合适,因为您需要使用.products_SKU数组中的数据构建自定义输出。

Use this alternative using the functions reduce and find . 使用此功能使用reducefind函数。

 var data = { products: [{ products_number: 14, products_ID: 'lvs_jeans-man', products_seller: 'a', products_SKU: [{ productSKU_ID: 'nfl_lvs_jeans-man_xl_bl-stripe', productSKU_size: 'XL', productSKU_color: 'Blue_White' }, { productSKU_ID: 'nfl_lvs_jeans-man_xl_bk', productSKU_size: 'XL', productSKU_color: 'Black' } ] }, { products_number: 15, products_ID: 'lvs_jeans-man', products_seller: 'b', products_SKU: [{ productSKU_ID: 'nfl_lvs_jeans-man_xl_bk', productSKU_size: 'XL', productSKU_color: 'Black' }] }, { products_number: 16, products_ID: 'lvs_jeans-man', products_seller: 'c', products_SKU: [{ productSKU_ID: 'nfl_lvs_jeans-man_xl_gy', productSKU_size: 'XL', productSKU_color: 'Grey', }] } ]}; var id = 'lvs_jeans-man' var size = 'XL' var color = 'Black' var result = data.products.reduce((a, p) => { var found; if (p.products_ID == id && (found = p.products_SKU.find(s => s.productSKU_size === size && s.productSKU_color === color))) { a.push({ products_number: p.products_number, products_ID: p.products_ID, products_seller: p.products_seller, productSKU_ID: found.productSKU_ID }); } return a; }, []); console.log(result) 
 .as-console-wrapper { max-height: 100% !important; top: 0; } 

It's too complicated for filter alone, you'll have to use more array methods, including reduce and find : 仅凭filter太复杂了,您将不得不使用更多的数组方法,包括reducefind

 const input = { products: [{ products_number: 14, products_ID: 'lvs_jeans-man', products_seller: 'a', products_SKU: [{ productSKU_ID: 'nfl_lvs_jeans-man_xl_bl-stripe', productSKU_size: 'XL', productSKU_color: 'Blue_White' }, { productSKU_ID: 'nfl_lvs_jeans-man_xl_bk', productSKU_size: 'XL', productSKU_color: 'Black' } ] }, { products_number: 15, products_ID: 'lvs_jeans-man', products_seller: 'b', products_SKU: [{ productSKU_ID: 'nfl_lvs_jeans-man_xl_bk', productSKU_size: 'XL', productSKU_color: 'Black' }] }, { products_number: 16, products_ID: 'lvs_jeans-man', products_seller: 'c', products_SKU: [{ productSKU_ID: 'nfl_lvs_jeans-man_xl_gy', productSKU_size: 'XL', productSKU_color: 'Grey', }] } ] }; const matchingProducts = input.products.filter(({ products_ID }) => products_ID === 'lvs_jeans-man'); const output = matchingProducts.reduce((matches, product) => { const foundSizeObj = product.products_SKU.find(({ productSKU_color, productSKU_size }) => { return productSKU_size === 'XL' && productSKU_color === 'Black'; }); if (!foundSizeObj) return matches; const match = {...product}; delete match.products_SKU; match.productSKU_ID = foundSizeObj.productSKU_ID; matches.push(match); return matches; }, []); console.log(output); 

You can filter by id first and then map products with first found productSKU, take out the products with undefined productSKU and map that to a result type: 您可以先按ID过滤,然后将具有第一个找到的productSKU的产品映射,取出具有未定义productSKU的产品并将其映射到结果类型:

 const products = [ { products_number: 14, products_ID: 'lvs_jeans-man', products_seller: 'a', products_SKU: [ { productSKU_ID: 'nfl_lvs_jeans-man_xl_bl-stripe', productSKU_size: 'XL', productSKU_color: 'Blue_White' }, { productSKU_ID: 'nfl_lvs_jeans-man_xl_bk', productSKU_size: 'XL', productSKU_color: 'Black' } ] }, { products_number: 15, products_ID: 'lvs_jeans-man', products_seller: 'b', products_SKU: [ { productSKU_ID: 'nfl_lvs_jeans-man_xl_bk', productSKU_size: 'XL', productSKU_color: 'Black' } ] }, { products_number: 16, products_ID: 'lvs_jeans-man', products_seller: 'c', products_SKU: [ { productSKU_ID: 'nfl_lvs_jeans-man_xl_gy', productSKU_size: 'XL', productSKU_color: 'Grey', } ] } ]; const filterProducts = products => (id,size,color) => products.filter(//filter by id first product=>product.products_ID===id ) .map(//map to products with filtered productSKU product=>({ ...product, products_SKU: product.products_SKU.find( info=> info.productSKU_size===size && info.productSKU_color===color ) }) ) .filter(//take out empty products_SKU product=> product.products_SKU!==undefined ); const mapToResult = product => ({ products_number: product.products_number, products_ID: product.products_ID, products_seller: product.products_seller, productSKU_ID: product.products_SKU.productSKU_ID }); console.log( filterProducts(products)("lvs_jeans-man","XL","Black") .map(mapToResult) ); 

Update 更新

const myFunction = arg => otherArg => 22

Is a function that returns a function, without the arrow syntax it would look like this: 是一个返回函数的函数,没有箭头语法,它看起来像这样:

function myFunction(arg){
  return function(otherArg){return 22; }
}

In the filterProducts you can use it to have filter linked to a set of products, for example: 在filterProducts中,您可以使用它使过滤器链接到一组产品,例如:

const filterPants = filterProducts(products.filter(pantsOnly))

The optimized answer from Ele would look like this: 来自Ele的优化答案如下所示:

var result = data.products.reduce((a, p) => {
  if (p.products_ID == id) {
    //only check found if id matches
    const found = p.products_SKU.find(
      s => s.productSKU_size === size && s.productSKU_color === color
    );
    if(!found){
      return a;//early return
    }
    a.push({
      products_number: p.products_number,
      products_ID: p.products_ID,
      products_seller: p.products_seller,
      productSKU_ID: found.productSKU_ID
    })
  }

  return a;
}, []);
const finalProducts = this.products.reduce((final, product) =>  {
  if (product.id === this.id || !this.id) {
    return[...final, ...product.products_SKU.reduce((acc, p) => {
      if (p.productSKU_size === this.size && p.productSKU_color === this.color) {
        return [...acc, {
          products_number: product.products_number,
          products_ID: product.products_ID,
          products_seller: product.products_seller,
          productSKU_ID: p.productSKU_ID
        }];
      }
      return acc;
    }, [])];
  }
  return final;
}, []);

finalProducs will be your expected output. finalProducs将是您的预期输出。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM