Jak używać ES6 Fat Arrow do .filter () tablicy obiektów

139

Próbuję użyć funkcji strzałki ES6 w .filtercelu zwrócenia dorosłych (Jack i Jill). Wygląda na to, że nie mogę użyć instrukcji if.

Co muszę wiedzieć, aby to zrobić w 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);

Mój działający przykład ES5:

let adults2 = family.filter(function (person) {
  if (person.age > 18) { return person; }
});
Henry Zhu
źródło
(8:37) SyntaxError: unknown: Nieoczekiwany token (8:37) | let adults = family.filter (person => if (person.age> 18) people);
Henry Zhu

Odpowiedzi:

236

Wygląda na to, że nie mogę użyć instrukcji if.

Strzałka funkcje albo umożliwić użycie wyrażenia lub do bloku , jak ich ciała. Przekazywanie wyrazu

foo => bar

odpowiada następnemu blokowi

foo => { return bar; }

Jednak,

if (person.age > 18) person

nie jest wyrażeniem, ifjest stwierdzeniem. Dlatego musiałbyś użyć bloku, gdybyś chciał użyć ifw funkcji strzałkowej:

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

Chociaż technicznie rozwiązuje to problem, jest to mylące użycie .filter, ponieważ sugeruje, że musisz zwrócić wartość, która powinna być zawarta w tablicy wyjściowej. Jednak wywołanie zwrotne przekazane do .filterpowinno zwrócić wartość logiczną , tj. trueOr false, wskazującą, czy element powinien zostać uwzględniony w nowej tablicy, czy nie.

Więc wszystko, czego potrzebujesz, to

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

W ES5:

family.filter(function (person) {
  return person.age > 18;
});
Felix Kling
źródło
Ach, co za świetne wyjaśnienie. W .filter () jeśli nic nie jest zwracane dla obiektu, przyjmuje się, że jest fałszywe? Na przykład w przykładzie z ES5 zwracane są tylko prawdziwe elementy.
Henry Zhu
2
@HenryZhu: Tak. Ale mój przykład zawsze zwraca albo falsealbo true, ponieważ person.age > 18zawsze jest albo falsealbo true.
Felix Kling
Wersja z „niezablokowanym” jeśli miała powrócić person(oczywiście nie robi tego, jak wskazałeś ...). Gdyby Twoja pierwsza korekta faktycznie to zrobiła ( foo => { if (person.age > 18) return person }), dostałbyś dokładny odpowiednik tego, co zostało użyte w kodzie ES5. Chociaż jest to mylący kod, DZIAŁA i rozwiąże problem. return personbędzie zmuszać truei żaden powrót nie „powróci” undefined, do czego zostanie zmuszony false.
Amit
1
@Amit: Jasne. Pomyślałem, że skoro inna odpowiedź to sugeruje, nie musiałbym. Jednak może to być mylące, więc zaktualizowałem go.
Felix Kling
2
@ just-boris: Nie jestem pewien, co to by tu osiągnęło .filter. Czy ogólnie masz na myśli funkcje strzałek?
Felix Kling
46

Nie możesz niejawnie powrócić z if, potrzebujesz nawiasów klamrowych:

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

Można to jednak uprościć:

let adults = family.filter(person => person.age > 18);
Kit Sunde
źródło
Świetnie, drugi działa. Pierwsza zwraca pustą tablicę. Jakieś pomysły?
Henry Zhu
1
@HenryZhu: Działa dobrze (prawdopodobnie coś innego jest nie tak z twoim kodem lub transpilerem). Ale to i tak nie jest właściwy sposób.
Felix Kling
1
Jak by to zrobiono, gdybyś miał inne oświadczenie? Próbuję zobaczyć to z trójskładnikiem, ale nie mogę zidentyfikować poprawnej składni
Winnemucca
@stevek Dokładnie tak, jak w przypadku normalnej funkcji, jak w pierwszym przykładzie.
Kit Sunde,
0

Tak proste, jak tylko możesz 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)

Pon.
źródło
0

Oto moje rozwiązanie dla tych, którzy używają hook; Jeśli wystawiasz przedmioty w swojej siatce i chcesz usunąć wybrany przedmiot, możesz skorzystać z tego rozwiązania.

var list = data.filter(form => form.id !== selectedRowDataId);
setData(list);
Sabri Meviş
źródło