如何使用ES6的“Fat Arrow”来对对象数组进行.filter()筛选

163

我正在尝试使用ES6箭头函数和.filter来返回成年人(Jack和Jill)。看起来我不能使用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) 语法错误:unknown: 意外的标记 (8:37) |let adults = family.filter(person => if (person.age > 18) people); - hzhu
6个回答

261

看起来我不能使用if语句。

箭头函数允许使用一个表达式作为函数体。传递一个表达式

foo => bar

等价于以下代码块:

foo => { return bar; }

然而,

if (person.age > 18) person

不是表达式,if是一个语句。因此,如果你想在箭头函数中使用if,你需要使用一个块:

foo => {  if (person.age > 18) return person; }
虽然这在技术上解决了问题,但这是一种令人困惑的.filter使用方式,因为它表明您必须返回应该包含在输出数组中的值。然而,传递给.filter的回调函数应该返回一个布尔值,即truefalse,指示是否应该将元素包含在新数组中。所以你只需要:
family.filter(person => person.age > 18);

在 ES5 中:

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

啊,讲解得真好。在 .filter() 中,如果一个对象没有返回任何值,则被视为 false 吗?例如,在你的 ES5 示例中,只有 true 元素被返回。 - hzhu
2
@HenryZhu:是的。但是我的例子总是返回falsetrue,因为person.age > 18总是要么是false要么是true - Felix Kling
1
@Amit:好的,我本来以为因为其他答案已经提到了这一点,我就不用再更新了。不过这可能会让人感到困惑,所以我还是更新了一下。 - Felix Kling
2
@just-boris:不确定在 .filter 中这样做会有什么作用。你是指箭头函数吗? - Felix Kling
@FelixKling,一般来说是这样的。对于箭头函数,在mapreduce和其他地方也能很好地工作。在这里,比较就足够了。 - just-boris
显示剩余5条评论

55

你不能用一个 if 隐式地返回值,需要使用花括号:

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

然而,它可以简化:

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

太棒了,第二个可行。第一个返回一个空数组。有什么想法吗? - hzhu
1
@HenryZhu:它运行得非常好(可能是你的代码或转译器出了问题)。但无论如何,这不是正确的方法。 - Felix Kling
1
如果有else语句,应该如何处理?我尝试使用三元运算符来实现,但似乎无法确定正确的语法。 - Winnemucca
@stevek 就像你在第一个例子中使用普通函数一样。 - Kit Sunde

5
return arrayname.filter((rec) => rec.age > 18)

将此内容写入方法中并调用它


3

使用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)


2

以下是我对使用hook的用户提供的解决方案;如果您正在列表中列出项目并想要删除所选项目,则可以使用此解决方案。

var list = data.filter(form => form.id !== selectedRowDataId);
setData(list);

0
另一个不错的选择是使用三元运算符,就像在映射中使用过滤器一样,并使用过滤器去掉空值。

var family = [{"name":"Jack",  "age": 26},
              {"name":"Jill",  "age": 22},
              {"name":"James", "age": 5 },
              {"name":"Jenny", "age": 0 }];
              
let adults = family.map(person => person.age < 18?person:null).filter(Boolean);

// or if you are afraid about filter(Boolean) you could use filter(person => person != null);

adults.forEach(element => console.log(element))


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接