繁体   English   中英

我正在根据字符串数组过滤数组元素,但是,我将字符串数组转换为对象数组。 我需要另一个循环吗?

[英]I'm filtering an array elements based on an array of strings, however, I'm turning the string array into an array of objects. Do I need another loop?

我有一个元素数组,其中每个元素都是来自某个游戏的卡片,并且我成功地根据另一个数组过滤卡片,如下所示:

let regions = ['Noxus', 'Demacia', 'Shadow Isles', 'Freljord', 'Ionia', 'Piltover & Zaun']

filteredByRegion(cards){
    return cards.filter((card) => {
        return this.regions.includes(card.region)
    })
}

但是,现在我试图将字符串数组转换为对象数组,其中字符串将只是对象的属性之一。

let regions = [
    { name: "Noxus", active: true },
    { name: "Demacia", active: true },
    { name: "Shadow Isles", active: false },
    { name: "Freljord", active: true },
    { name: "Ionia", active: true },
    { name: "Piltover & Zaun", active: false },
]

现在我只想从将active属性设置为true区域获取卡片。 这意味着我需要在进行卡片过滤之前获取所有活动区域。 所以我把函数改成这样:

filteredByRegion(cards){
    let activeRegions = regions.filter((region) => {
        return region.active === true
    })

    return cards.filter((card) => {
        return this.regions.includes(card.region)
    })
}

现在我有点困惑如何更改cards.filter()以便它只返回其区域属性与我的activeRegions变量中的活动区域之一匹配的卡片。 我是否需要在卡片过滤器中使用 for 循环来循环每个活动区域并将返回this.regions.includes(card.region)放在该循环中?

首先通过过滤和映射对象的regions数组来创建活动区域的集合(或数组)。 然后你可以创建另一个包含在这些活动区域中的this.regions集。 最后,根据是否包含在该 Set 中过滤cards参数:

filteredByRegion(cards){
  const activeRegionsSet = new Set(
    regions
      .filter(({ active }) => active)
      .map(({ name }) => name)
  );
  const theseActiveRegions = new Set(this.regions.filter(region => activeRegionsSet.has(region)));
  return cards.filter(card => theseActiveRegions.has(card.region));
}

或者,如果你不喜欢解构:

filteredByRegion(cards){
  const activeRegionsSet = new Set(
    regions
      .filter(obj => obj.active)
      .map(obj => obj.name)
  );
  const theseActiveRegions = new Set(this.regions.filter(region => activeRegionsSet.has(region)));
  return cards.filter(card => theseActiveRegions.has(card.region));
}

Sets 是为了降低计算复杂度( Set#hasO(1) ,而Array#includesO(n) )。 但是,如果您更喜欢数组,则相同的代码将如下所示:

filteredByRegion(cards){
  const activeRegions = regions
    .filter(({ active }) => active)
    .map(({ name }) => name);
  const theseActiveRegions = this.regions.filter(region => activeRegions.includes(region));
  return cards.filter(card => theseActiveRegions.includes(card.region));
}

这无关紧要,但您可以通过推入条件测试只迭代原始regions数组一次而不是两次,尽管它的功能较弱:

const activeRegions = [];
for (const { active, name } of regions) {
  if (active) {
    activeRegions.push(name);
  }
}

暂无
暂无

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

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