递归过滤对象数组

时间:2018-03-31 02:06:55

标签: javascript

我有这些数据结构

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'

如何过滤符合这些条件的项目

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

所需的输出是

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

我试过的是首先过滤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)))

如何实现所需的输出?

4 个答案:

答案 0 :(得分:1)

函数过滤器不合适,因为您需要使用数组strongSelf中的数据构建自定义输出。

使用.products_SKUreduce函数。

使用此替代方法

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

答案 1 :(得分:0)

单独使用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);

答案 2 :(得分:0)

您可以先按ID过滤,然后使用首次找到的productSKU映射产品,请使用未定义的productSKU取出产品并将其映射到结果类型:



Make




更新

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

是一个返回函数的函数,没有箭头语法,它看起来像这样:

const myFunction = arg => otherArg => 22

在filterProducts中,您可以使用它将过滤器链接到一组产品,例如:

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

Ele的优化答案如下:

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

答案 3 :(得分:0)

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将是您的预期输出。