在JavaScript中过滤一个数组内包含对象的另一个数组中的内容。

3

我有一个对象,需要一个函数来按类型或弱点(由用户决定)过滤宝可梦(整个对象)。 例如:“用户需要过滤所有火属性的宝可梦”,结果将是一个包含每个火属性宝可梦对象的数组。

var POKEMON = {
  "pokemon": [{
    "id": 1,
    "num": "001",
    "name": "Bulbasaur",
    "img": "https://assets.pokemon.com/assets/cms2/img/pokedex/full/001.png",
    "type": [
      "Grass",
      "Poison"
    ],
    "height": "0.71 m",
    "weight": "6.9 kg",
    "candy": "Bulbasaur Candy",
    "candy_count": 25,
    "egg": "2 km",
    "spawn_chance": 0.69,
    "avg_spawns": 69,
    "spawn_time": "20:00",
    "multipliers": [1.58],
    "weaknesses": [
      "Fire",
      "Ice",
      "Flying",
      "Psychic"
    ],
    "next_evolution": [{
      "num": "002",
      "name": "Ivysaur"
    }, {
      "num": "003",
      "name": "Venusaur"
    }]
  },{
    "id": 2,
    "num": "002",
    "name": "Ivysaur",
    "img": "https://assets.pokemon.com/assets/cms2/img/pokedex/full/002.png",
    "type": [
      "Grass",
      "Poison"
    ],
    "height": "0.99 m",
    "weight": "13.0 kg",
    "candy": "Bulbasaur Candy",
    "candy_count": 100,
    "egg": "Not in Eggs",
    "spawn_chance": 0.042,
    "avg_spawns": 4.2,
    "spawn_time": "07:00",
    "multipliers": [
      1.2,
      1.6
    ],
    "weaknesses": [
      "Fire",
      "Ice",
      "Flying",
      "Psychic"
    ],
    "prev_evolution": [{
      "num": "001",
      "name": "Bulbasaur"
    }],
    "next_evolution": [{
      "num": "003",
      "name": "Venusaur"
    }]
  },
... (+149 other pokemon)

我已经有一个可用的函数,但我不想使用for循环:

const filterPokemon = (data, whatToFilter, valueToCompare) => {  
  return data.filter(pokemon => {
    for(let i = 0 ; i < pokemon[whatToFilter].length ; i++){
      if(pokemon[whatToFilter][i] === valueToCompare){       
        return pokemon;
      }
    }
  });
};

filterPokemon(POKEMON.pokemon, "type", "Fire");
3个回答

2
使用.includes代替,以查看pokemon[whatToFilter]数组中是否有任何项等于valueToCompare:
const filterPokemon = (data, whatToFilter, valueToCompare) => {  
  return data.filter(creatureObj => (
    creatureObj[whatToFilter].includes(valueToCompare)
  ));
};

顺便提一下,这可能有点基于个人观点,但你可以考虑将变量名从pokemon(例如这里我使用了“creatureObj”)更改,因为“pokemon”既可以是单数也可以是复数,因此并不完全清楚它是什么样的对象。

如果你想的话,也可以通过解构参数来完全避免这种情况:

const filterPokemon = (data, whatToFilter, valueToCompare) => {  
  return data.filter(({ [whatToFilter]: arr }) => (
    arr.includes(valueToCompare)
  ));
};

1
您已经掌握了第一部分,但只需使用数组find()运算符进行过滤,或者由于这些是简单的基元数组,您可以只使用.indexOf(value)> -1或.includes()或其他几个运算符。我更喜欢find,因为它也适用于复杂类型。
const filterPokemon = (pokemonList, propToFilter, value) => {  
  return pokemonList.filter(pokemon => {
    return pokemon[propToFilter].find(p => p === value);
  });
};

1
另一个选择是在 filter 函数中使用 Array.some()
const filterPokemon = (data, whatToFilter, valueToCompare) =>
{  
  return data.filter(pokemon => pokemon[whatToFilter].some(x => x === valueToCompare));
}

例子:

示例:

var POKEMON = {
  "pokemon": [{
    "id": 1,
    "num": "001",
    "name": "Bulbasaur",
    "img": "https://assets.pokemon.com/assets/cms2/img/pokedex/full/001.png",
    "type": [
      "Grass",
      "Poison"
    ]
  },
  {
    "id": 2,
    "num": "002",
    "name": "Ivysaur",
    "img": "https://assets.pokemon.com/assets/cms2/img/pokedex/full/002.png",
    "type": [
      "Grass",
      "Poison",
      "Fire"
    ],
  }
]};

const filterPokemon = (data, whatToFilter, valueToCompare) =>
{  
    return data.filter(pokemon => pokemon[whatToFilter].some(x => x === valueToCompare));
}
    
let res = filterPokemon(POKEMON.pokemon, "type", "Fire");
console.log(res);
.as-console {background-color:black !important; color:lime;}
.as-console-wrapper {max-height:100% !important; top:0;}


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接