Como usar o ES6 Fat Arrow para .filter () uma matriz de objetos

139

Estou tentando usar a função de seta ES6 .filterpara retornar adultos (Jack & Jill). Parece que não posso usar uma instrução if.

O que eu preciso saber para fazer isso no ES6?

var family = [{"name":"Jack",  "age": 26},
              {"name":"Jill",  "age": 22},
              {"name":"James", "age": 5 },
              {"name":"Jenny", "age": 2 }];

let adults = family.filter(person => if (person.age > 18) person); // throws error

(8:37) SyntaxError: unknown: Unexpected token (8:37)
|let adults = family.filter(person => if (person.age > 18) person);

Meu exemplo de trabalho do ES5:

let adults2 = family.filter(function (person) {
  if (person.age > 18) { return person; }
});
Henry Zhu
fonte
(8:37) SintaxeErro: desconhecido: token inesperado (8:37) | deixe adult = family.filter (person => if (person.age> 18) people);
Henry Zhu

Respostas:

236

Parece que não posso usar uma instrução if.

As funções de seta permitem usar uma expressão ou um bloco como corpo. Passando uma expressão

foo => bar

é equivalente ao seguinte bloco

foo => { return bar; }

Contudo,

if (person.age > 18) person

não é uma expressão, ifé uma afirmação. Portanto, você teria que usar um bloco, se quisesse usar ifem uma função de seta:

foo => {  if (person.age > 18) return person; }

Embora isso resolva tecnicamente o problema, esse é um uso confuso .filter, pois sugere que você deve retornar o valor que deve estar contido na matriz de saída. No entanto, o retorno de chamada passado para .filterdeve retornar um booleano , trueou seja false, indicando se o elemento deve ser incluído na nova matriz ou não.

Então tudo que você precisa é

family.filter(person => person.age > 18);

No ES5:

family.filter(function (person) {
  return person.age > 18;
});
Felix Kling
fonte
Ah, que ótima explicação. Em .filter (), se nada é retornado para um objeto, ele é assumido como falso? Por exemplo, no seu exemplo ES5, apenas os elementos verdadeiros são retornados.
Henry Zhu
2
@HenryZhu: Sim. Mas meu exemplo sempre retorna um falseou true, já que person.age > 18é sempre um falseou outro true.
Felix Kling
A versão com o "desbloqueado" se deveria retornar person(é claro que não faz isso como você apontou ...). Se a sua primeira correção realmente fizesse isso ( foo => { if (person.age > 18) return person }), você obteria o equivalente exato do OP usado no código ES5. Embora esse seja um código confuso, ele funciona e resolverá o problema. return personcoagirá truee nenhum retorno "retornará" undefined, o que será coagido false.
Amit
1
@Mit: com certeza. Eu pensei que, porque a outra resposta sugeria, eu não precisaria. No entanto, isso pode ser confuso, então eu atualizei.
Felix Kling
2
@ just-boris: Não tenho certeza do que isso alcançaria aqui .filter. Você quer dizer funções de seta em geral?
Felix Kling
46

Você não pode retornar implicitamente com um if, seria necessário o aparelho:

let adults = family.filter(person => { if (person.age > 18) return person} );

No entanto, pode ser simplificado:

let adults = family.filter(person => person.age > 18);
Kit Sunde
fonte
Impressionante, o segundo funciona. O primeiro retorna uma matriz vazia. Alguma ideia?
Henry Zhu
1
@ HenryZhu: Funciona muito bem (provavelmente algo mais está errado com seu código ou transpilador). Mas esse não é o caminho certo de qualquer maneira.
Felix Kling
1
Como isso seria feito no caso de você ter uma declaração else? Eu estou tentando ver isso com um ternário, mas parece que não consegue identificar a sintaxe correta
Winnemucca
@ stevek Exatamente como você faria com uma função normal, como no primeiro exemplo.
Kit Sunde
0

Tão simples quanto você pode usar const adults = family.filter(({ age }) => age > 18 );

const family =[{"name":"Jack",  "age": 26},
              {"name":"Jill",  "age": 22},
              {"name":"James", "age": 5 },
              {"name":"Jenny", "age": 2 }];

const adults = family.filter(({ age }) => age > 18 );

console.log(adults)

Mo.
fonte
0

Aqui está a minha solução para quem usa hook; Se você estiver listando itens em sua grade e quiser remover o item selecionado, poderá usar esta solução.

var list = data.filter(form => form.id !== selectedRowDataId);
setData(list);
Sabri Meviş
fonte