【问题标题】:Filtering an array by using values in another array使用另一个数组中的值过滤数组
【发布时间】:2017-03-23 12:46:07
【问题描述】:

我有两个数组。一个存放产品,另一个存放过滤器(衬衫、裤子等)。所有产品都有一个 type 属性,可以是衬衫、裤子等,对应于过滤器。

我正在尝试制作一个选择器,该选择器将返回一个新数组,该数组缺少任何类型与任何过滤器匹配的产品。

export function filterProducts(products, filters) {
  return products.filter((item) => {
    return item.type === "hat";
  });
};

与此类似,除了显然检查每个过滤器,而不仅仅是“帽子”。我可以想到一些笨拙的方法来实现这一点,但我正在尝试找出更优雅的方法。我知道我必须在循环内循环,但我不能让它正常工作。 ES6/lodash 等都很好。

【问题讨论】:

  • 你可以使用someindexOfincludes,这些都是数组方法。
  • item => filters.includes(item.type)?
  • 让我直截了当地说:您要保留与过滤器匹配的那些,还是相反?您的帖子自相矛盾...

标签: javascript arrays ecmascript-6


【解决方案1】:

假设filters 是一个包含您要查找的类型的字符串数组,您可以使用Array.prototype.some 搜索filters 数组来过滤它。

var products = [
    {
      name: 'Foo',
      type: 'hat'
    },
    {
      name: 'Bar',
      type: 'shirt'
    },
    {
      name: 'Baz',
      type: 'pants'
    },
    {
      name: 'Foobar',
      type: 'hat'
    },
    {
      name: 'Falsy Type',
      type: ''
    },
  ],
  filters = ['hat', 'pants', ''];

function filterProducts(products, filters) {
  return products.filter((item) => {
    return !filters.some(filter => item.type === filter);
  });
};

console.log(filterProducts(products, filters));

【讨论】:

  • 我实际上给出了错误的代码 sn-p,它可能使回答我的问题变得混乱。我最终使用了:!filters.find(filter => item.type === filter) 这给了我想要的结果。感谢您的帮助:)
  • @Ian 啊,我似乎已经掩盖了文本中的“遗漏”。我已经更新了答案以反映您的目标。
  • 不,您应该使用some 而不是find 来检查数组中是否存在元素。想象一下 item.type 是假的……
  • @Bergi find 只会在item.typefilters 中同时存在虚假项目的情况下才会失败;因为filters 是一个非空字符串数组(因此总是真实的),除非出现拼写错误find 有效。也就是说,你说得对,some 更适合这个,它使它更防弹。我已经更新了示例。
  • 谢谢!顺便说一句,如果您关心不支持 some 的过时浏览器,那么只有 IE8,甚至需要为 indexOf 使用 polyfill
【解决方案2】:

对此的另一种看法!

'use strict'
const filters = ['hat','shirt','pant'];
const products = [{
                    sku: 101,
                    type: 'hat'
                 }, {
                    sku: 102,
                    type: 'hat'
                 }, {
                    sku: 103,
                    type: 'shirt'
                 }, {
                    sku: 104,
                    type: 'pant'
                 }, {
                    sku: 101,
                    type: 'pant'
                 }, {
                    sku: 101,
                    type: 'shirt'
                 }]


const filterize = function (products, filters){
    let map = {};
    filters.forEach(function(filter){
        map[filter] = [];
    })
    products.forEach(function(product){
        if(typeof map[product.type] !== undefined){
            map[product.type].push(product);
        }
    })
    return map;
}


console.log(filterize(products, filters));

这将返回一个地图,其中您的过滤器作为键和值作为与过滤器对应的产品列表。下面的示例输出:

{ hat: [ { sku: 101, type: 'hat' }, { sku: 102, type: 'hat' } ],
  shirt: [ { sku: 103, type: 'shirt' }, { sku: 101, type: 'shirt' } ],
  pant: [ { sku: 104, type: 'pant' }, { sku: 101, type: 'pant' } ] }

【讨论】:

    猜你喜欢
    • 2020-06-24
    • 2018-12-12
    • 2017-01-24
    • 1970-01-01
    • 2017-09-16
    • 1970-01-01
    • 2012-03-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多