Как использовать ES6 Fat Arrow для .filter () массива объектов

139

Я пытаюсь использовать функцию стрелки ES6 .filterдля возврата взрослых (Джек и Джилл). Кажется, я не могу использовать оператор if.

Что мне нужно знать, чтобы сделать это в 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);

Мой рабочий пример ES5:

let adults2 = family.filter(function (person) {
  if (person.age > 18) { return person; }
});
Генри Чжу
источник
(8:37) SyntaxError: unknown: неожиданный токен (8:37) | let adults = family.filter (person => if (person.age> 18) people);
Генри Чжу

Ответы:

236

Кажется, я не могу использовать оператор if.

Стрелка функции либо позволяют использовать выражение или в блок , как их тело. Передача выражения

foo => bar

эквивалентно следующему блоку

foo => { return bar; }

Тем не мение,

if (person.age > 18) person

это не выражение, ifэто утверждение. Следовательно, вам придется использовать блок, если вы хотите использовать ifв функции стрелки:

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

Хотя это технически решает проблему, это запутанное использование .filter, потому что предполагает, что вы должны возвращать значение, которое должно содержаться в выходном массиве. Однако переданный обратный вызов .filterдолжен возвращать логическое значение , т. Е. trueИли false, указывающее, должен ли элемент быть включен в новый массив или нет.

Так что все, что вам нужно, это

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

В ES5:

family.filter(function (person) {
  return person.age > 18;
});
Феликс Клинг
источник
Ах, какое замечательное объяснение. В .filter (), если для объекта ничего не возвращается, он считается ложным? Например, в вашем примере ES5 возвращаются только истинные элементы.
Генри Чжу
2
@HenryZhu: Да. Но мой пример всегда возвращает либо falseили true, так person.age > 18как всегда либо либо, falseлибо true.
Феликс Клинг
Версия с «неблокированным» if должна была вернуться person(конечно, она не делает этого, как вы указали ...). Если бы ваша первая поправка действительно сделала это ( foo => { if (person.age > 18) return person }), вы бы получили точный эквивалент того, что OP использовал в коде ES5. Хотя это запутанный код, он работает и решит проблему. return personбудет принудительно trueвозвращаться, а возврат не будет «возвращаться» undefined, что будет принудительно выполнено false.
Амит
1
@Amit: конечно. Я думал, потому что другой ответ предложил это, мне не пришлось бы. Однако это может сбивать с толку, поэтому я обновил его.
Феликс Клинг
2
@ just-boris: Не уверен, что это будет достигнуто здесь .filter. Вы имеете в виду функции стрелок в целом?
Феликс Клинг
46

Вы не можете неявно вернуться с if, вам понадобятся фигурные скобки:

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

Это может быть упрощено, хотя:

let adults = family.filter(person => person.age > 18);
Кит Сунде
источник
Круто, второй работает. Первый возвращает пустой массив. Любые идеи?
Генри Чжу
1
@HenryZhu: Он работает просто отлично (возможно, что-то не так с вашим кодом или транспилером). Но это не совсем так.
Феликс Клинг
1
Как это будет сделано в случае, если у вас есть еще заявление? Я пытаюсь увидеть это с троичным, но не могу определить правильный синтаксис
Winnemucca
@stevek Точно так же, как с обычной функцией, как в первом примере.
Кит Сунде
0

Так просто, как вы можете использовать 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)

Пн.
источник
0

Вот мое решение для тех, кто использует hook; Если вы перечисляете элементы в своей сетке и хотите удалить выбранный элемент, вы можете использовать это решение.

var list = data.filter(form => form.id !== selectedRowDataId);
setData(list);
Сабри Мевиш
источник