Cách sử dụng ES6 Fat Arrow để .filter () một mảng các đối tượng


139

Tôi đang cố gắng sử dụng chức năng mũi tên ES6 .filterđể trả lại người lớn (Jack & Jill). Có vẻ như tôi không thể sử dụng một câu lệnh if.

Tôi cần biết những gì để làm điều này trong 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);

Ví dụ ES5 làm việc của tôi:

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

(8:37) Cú phápError: unknown: Mã thông báo bất ngờ (8:37) | let dành cho người lớn = gia đình.filter (người => if (person.age> 18) người);
Henry Zhu

Câu trả lời:


236

Có vẻ như tôi không thể sử dụng một câu lệnh if.

Các hàm mũi tên hoặc cho phép sử dụng một biểu thức hoặc một khối làm cơ thể của chúng. Vượt qua một biểu thức

foo => bar

tương đương với khối sau

foo => { return bar; }

Tuy nhiên,

if (person.age > 18) person

không phải là một biểu thức, iflà một tuyên bố. Do đó, bạn sẽ phải sử dụng một khối, nếu bạn muốn sử dụng iftrong hàm mũi tên:

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

Trong khi về mặt kỹ thuật giải quyết vấn đề, đây là một cách sử dụng khó hiểu .filter, bởi vì nó gợi ý rằng bạn phải trả về giá trị nên có trong mảng đầu ra. Tuy nhiên, cuộc gọi lại được chuyển đến .filtersẽ trả về Boolean , nghĩa là truehoặc false, cho biết phần tử có nên được đưa vào mảng mới hay không.

Vì vậy, tất cả những gì bạn cần là

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

Trong ES5:

family.filter(function (person) {
  return person.age > 18;
});

Ah, thật là một lời giải thích tuyệt vời. Trong .filter () nếu không có gì được trả về cho một đối tượng, nó được coi là sai? Ví dụ, trong ví dụ ES5 của bạn, chỉ các phần tử thực được trả về.
Henry Zhu

2
@HenryZhu: Vâng. Nhưng ví dụ của tôi luôn trả về falsehoặc true, vì person.age > 18luôn luôn là falsehoặc true.
Felix Kling

Phiên bản với "không bị chặn" nếu được cho là quay trở lại person(tất nhiên nó không làm điều đó như bạn đã chỉ ...). Lần sửa lỗi đầu tiên của bạn thực sự đã làm điều đó ( foo => { if (person.age > 18) return person }), bạn sẽ nhận được chính xác tương đương với những gì OP đã sử dụng trong mã ES5. Mặc dù đó là một mã khó hiểu, nhưng nó vẫn hoạt động và SILL giải quyết vấn đề. return personsẽ ép buộc truevà không trả lại sẽ "trở lại" undefined, mà sẽ bị ép buộc false.
Amit

1
@Amit: Chắc chắn rồi. Tôi nghĩ bởi vì câu trả lời khác gợi ý nó, tôi sẽ không phải. Tuy nhiên, điều này có thể gây nhầm lẫn, vì vậy tôi đã cập nhật nó.
Felix Kling

2
@ just-boris: Không chắc điều này sẽ đạt được ở đây với .filter. Bạn có nghĩa là chức năng mũi tên nói chung?
Felix Kling

45

Bạn không thể hoàn toàn quay lại với một if, bạn sẽ cần niềng răng:

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

Nó có thể được đơn giản hóa mặc dù:

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

Tuyệt vời, cái thứ hai hoạt động. Cái đầu tiên trả về một mảng trống. Có ý kiến ​​gì không?
Henry Zhu

1
@HenryZhu: Nó hoạt động tốt (có thể có gì đó không đúng với mã hoặc bộ chuyển mã của bạn). Nhưng dù sao đó không phải là cách đúng đắn.
Felix Kling

1
Làm thế nào điều này sẽ được thực hiện trong trường hợp bạn có một tuyên bố khác? Tôi đang cố gắng để thấy điều này với một ternary nhưng dường như không thể xác định đúng cú pháp
Winnemucca

@stevek Chính xác như bạn làm với một hàm bình thường như trong ví dụ đầu tiên.
Kit Sunde

0

Đơn giản như bạn có thể sử dụng 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

Đây là giải pháp của tôi cho những người sử dụng hook; Nếu bạn đang liệt kê các mục trong lưới của bạn và muốn xóa mục đã chọn, bạn có thể sử dụng giải pháp này.

var list = data.filter(form => form.id !== selectedRowDataId);
setData(list);
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.