Cómo usar ES6 Fat Arrow para .filter () una matriz de objetos

139

Estoy tratando de usar la función de flecha ES6 con .filterpara regresar adultos (Jack & Jill). Parece que no puedo usar una declaración if.

¿Qué necesito saber para hacer esto en 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);

Mi ejemplo de trabajo de ES5:

let adults2 = family.filter(function (person) {
  if (person.age > 18) { return person; }
});
Henry Zhu
fuente
(8:37) SyntaxError: desconocido: token inesperado (8:37) | let adults = family.filter (person => if (person.age> 18) people);
Henry Zhu

Respuestas:

236

Parece que no puedo usar una declaración if.

Las funciones de flecha permiten usar una expresión o un bloque como su cuerpo. Pasando una expresión

foo => bar

es equivalente al siguiente bloque

foo => { return bar; }

Sin embargo,

if (person.age > 18) person

No es una expresión, ifes una declaración. Por lo tanto, tendría que usar un bloque, si quisiera usarlo ifen una función de flecha:

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

Si bien eso resuelve técnicamente el problema, este es un uso confuso .filter, porque sugiere que debe devolver el valor que debe estar contenido en la matriz de salida. Sin embargo, la devolución de llamada pasada a .filterdebería devolver un valor booleano , es decir, trueo false, que indica si el elemento debe incluirse en la nueva matriz o no.

Entonces todo lo que necesitas es

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

En ES5:

family.filter(function (person) {
  return person.age > 18;
});
Felix Kling
fuente
Ah, qué gran explicación. En .filter () si no se devuelve nada para un objeto, ¿se supone que es falso? Por ejemplo, en su ejemplo ES5, solo se devuelven los elementos verdaderos.
Henry Zhu
2
@HenryZhu: Sí. Pero mi ejemplo siempre devuelve falseo true, ya person.age > 18que siempre es falseo true.
Felix Kling
Se suponía que la versión con el "desbloqueado" debía regresar person(por supuesto, no lo hace como señaló ...). Si su primera corrección realmente hiciera eso ( foo => { if (person.age > 18) return person }), obtendría el equivalente exacto de lo que OP utilizó en el código ES5. Si bien ese es un código confuso, sí funciona y RESOLVERÁ el problema. return personforzará true, y ningún retorno "volverá" undefined, lo cual será forzado false.
Amit
1
@Amit: claro. Pensé que porque la otra respuesta lo sugería, no tendría que hacerlo. Sin embargo, esto puede ser confuso, así que lo actualicé.
Felix Kling
2
@ just-boris: No estoy seguro de lo que esto lograría aquí .filter. ¿Te refieres a las funciones de flecha en general?
Felix Kling
46

No puede regresar implícitamente con un if, necesitaría las llaves:

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

Sin embargo, se puede simplificar:

let adults = family.filter(person => person.age > 18);
Kit Sunde
fuente
Impresionante, el segundo funciona. El primero devuelve una matriz vacía. ¿Algunas ideas?
Henry Zhu
1
@HenryZhu: Funciona bien (probablemente algo más está mal con su código o transpiler). Pero esa no es la forma correcta de todos modos.
Felix Kling
1
¿Cómo se haría esto en caso de que tenga una declaración else? Estoy tratando de ver esto con un ternario pero parece que no puedo identificar la sintaxis correcta
Winnemucca
@stevek Exactamente como lo haría con una función normal como en el primer ejemplo.
Kit Sunde
0

Tan simple como puedes 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)

Mes.
fuente
0

Aquí está mi solución para aquellos que usan hook; Si está enumerando elementos en su cuadrícula y desea eliminar el elemento seleccionado, puede usar esta solución.

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