过滤对象数组对象数组的简单方法

时间:2017-07-23 16:29:45

标签: javascript

我正在尝试过滤一个包含对象数组对象的对象数组。例如,数组中的对象看起来像这样。

list=[...,
    {
        "types": [
            {
            "slot": 2,
            "type": 
                {
                    "url": "http://pokeapi.co/api/v2/type/4/",
                    "name": "poison"
                }
            },
            {
            "slot": 1,
            "type": 
                {
                    "url": "http://pokeapi.co/api/v2/type/12/",
                    "name": "grass"
                }
            }
        ],
        "name": 'bulbasaur'
    },...
]

我目前正在按名称和类似对象的类型过滤列表(this.props.search.search是一个字符串,示例是一个将调整的字符串示例列表):

    let filtered = this.props.pokemons.filter((pokemon)=>{
        return pokemon.name.toLowerCase().indexOf(this.props.search.search.toLocaleLowerCase())!==-1;
    })
    let example = ['fire', 'ice', 'water'];
    let filteredx= filtered.filter((pokemon)=>{
        return pokemon.types.filter((type)=>{
            return example.indexOf(type.type.name)!==-1
        }).length>0
    })

是否有将所有过滤器合并为一个而不是调用

的方法
array.filter(...).filter(...)

与将来一样,如果添加更多过滤器,我担心它最终会看起来像

array.filter(...).filter(...).filter(...).filter(...).filter(...)

任何帮助都将不胜感激。

4 个答案:

答案 0 :(得分:1)

您可以将这两个条件与&&

结合使用
let filteredx = this.props.pokemons.filter(pokemon =>
    pokemon.name.toLowerCase().includes(this.props.search.search.toLocaleLowerCase())
    && pokemon.types.some(type => example.includes(type.type.name))
)

请注意,您可以在条件中使用includessome,并在箭头函数中使用表达式语法(不带括号或return)。

您可以使用其他&&运算符添加更多条件。确保按照最简单的条件(最少需要工作)的顺序排列。

答案 1 :(得分:0)

如果阵列很小且性能不是问题;

select id, item
from (select t.*, count(*) over (partition by id) as cnt
      from t
     ) t
where cnt > 1 and regexp_like(item, '^(65|66)') or cnt = 1;

否则您可以尝试将条件组合到相同的过滤函数中。

答案 2 :(得分:0)

您可以在一个过滤器中组合所有过滤条件,而不是多次过滤。

而不是这样做......

let filtered1 = toFilter.filter((element) => {
    return condition1;
});

let filtered2 = filtered1.filter((element) => {
    return condition2;
});

...

let filteredN = filteredN_1.filter((element) => {
    return conditionN;
});

...您可以在单个过滤器中组合条件:

let filtered = toFilter.filter((element) => {
    return condition1 && condition2 && ... && conditionN;
});

如果其中一个条件非常长,您可以在单独的函数中轻松地对其进行抽象。这也使代码更具可读性和可维护性。

let filtered = toFilter.filter((element) => {
    const condition1 = computeCondition1(arg1, arg2);
    const condition2 = computeCondition2(arg1);
    ...
    const condition3 = computeCondition3(arg2, arg3, arg4);

    return condition1 && condition2 && ... && conditionN;
});

答案 3 :(得分:0)

您可以定义一个对象,该对象包含您要测试的宠物小精灵列表的每个第一级属性的属性。该值将是"测试逻辑"的谓词。这个属性。



const pokemons = [
  {"name":"poke1","types":[{"type":{"name":"poison"}},{"type":{"name":"grass"}}]},
  {"name":"poke2","types":[{"type":{"name":"fire"}},{"type":{"name":"grass"}}]},
  {"name":"poke3","types":[{"type":{"name":"ice"}},{"type":{"name":"water"}}]},
  {"name":"poke4","types":[{"type":{"name":"ice"}},{"type":{"name":"grass"}}]}
];

const filterOptions = {
  name: (name) => {
    return ["poke1", "poke5"].some(x => x === name);
  },
  types: (types) => {
    return ["ice", "water"].some(t => types.some(x => t === x.type.name));
  }
};

function filterList(list, options) {
  return list.filter(pokemon => {
    return Object.keys(options)
                 .some(key => {
                   if (key in pokemon) {
                     return filterOptions[key](pokemon[key]);
                   }
                 });
  });
}

const filtered = filterList(pokemons, filterOptions);
filtered.forEach(p => console.log(JSON.stringify(p)));