根据数组过滤对象列表

时间:2020-03-04 20:16:52

标签: javascript

问题,我有一个带有标签的产品列表,如下所示:

const products = [{
    "id": 1,
    "tags": {
      "option": ["A", "B"]
    }
  }, {
    "id": 2,
    "tags": {
      "option": ["B"],
      "type": ["A", "B", "C"]
    }
  }, {
    "id": 3,
    "tags": {
      "type": ["A"]
    }
  }, {
    "id": 4,
    "tags": {
      "option": ["B", "C"],
      "type": ["A", "C"]
    }
  }];

基于创建过滤器对象的复选框,如下所示:

var filter = {
  "option": [], 
  "type": []
}

以上内容将填写:

var filter = {
  "option": ["A"], // can contain more than one value
  "type": ["C", "B"] // can contain more than one value
}

应用此过滤器后,应返回以下内容:

const products = [{
    "id": 1,
    "tags": {
      "option": ["A", "B"]
    }
  }, {
    "id": 2,
    "tags": {
      "option": ["B"],
      "type": ["A", "B", "C"]
    }
  }, {
    "id": 4,
    "tags": {
      "option": ["B", "C"],
      "type": ["A", "C"]
    }
  }];

我要检查商品是否包含在产品列表中,如果要返回,则返回仅包含包含添加的过滤器的产品的新产品列表。有人可以朝正确的方向推动我吗?

当前,我正在尝试在products对象上执行.filter(),但我似乎无法使其与多个过滤器一起使用。

const products = [{
    "id": 1,
    "tags": {
      "option": ["B", "A"]
    }
  }, {
    "id": 2,
    "tags": {
      "option": ["B"],
      "type": ["A", "B", "C"]
    }
  }, {
    "id": 3,
    "tags": {
      "type": ["A"]
    }
  }, {
    "id": 4,
    "tags": {
      "option": ["B", "C"],
      "type": ["A", "C"]
    }
  }];

var filter = {
  "option": ["A"], 
  "type": ["C", "B"] 
}

function checkAvailability(arr, val) {
if (arr != undefined) {
  return arr.some(function(arrVal) {
      return val === arrVal;
    });
  }
}

const obj = []
const test = products.filter(product => {
  for(var i = 0; i < filter.option.length; i++) {
    return checkAvailability(product.tags.option, filter.option[i])
  }
})
console.log(test)

1 个答案:

答案 0 :(得分:1)

您可以使用带有键的数组并设置值,然后通过检查带有值的过滤器数组来过滤该数组。

const
    products = [{ id: 1, tags: { option: ["A", "B"] } }, { id: 2, tags: { option: ["B"], type: ["A", "B", "C"] } }, { id: 3, tags: { type: ["A"] } }, { id: 4, tags: { option: ["B", "C"], type: ["A", "C"] } }],
    filter = { option: ["A"], type: ["C", "B"] },
    filterArray = Object.entries(filter).map(([k, v]) => [k, Set.prototype.has.bind(new Set(v))]),
    result = products.filter(({ tags }) =>
        filterArray.some(([k, fn]) => (tags[k] || []).some(fn))
    );

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }