简体   繁体   English

在JavaScript中返回三元运算符reduce

[英]Return ternary operator in JavaScript reduce

I have a data structure like this: 我有这样的数据结构:

var example = [
    { name: "item1", year: 2013, value: 100 },
    { name: "item1", year: 2012, value:  97 },
    { name: "item3", year: 2013, value:  93 },
    { name: "item3", year: 2012, value:  91 },
    { name: "item2", year: 2012, value:  -6 },
    { name: "item2", year: 2011, value:  -5 },
    { name: "item4", year: 2012, value: -36 },
    { name: "item3", year: 2011, value:  93 },
    { name: "item4", year: 2013, value: -35 },
    { name: "item1", year: 2011, value:  98 },
    { name: "item2", year: 2013, value:  -7 },
    { name: "item4", year: 2011, value: -37 },
    { name: "item5", year: 2013, value:  58 },
    { name: "item5", year: 2012, value:  55 },
    { name: "item5", year: 2011, value:  54 }
];

I am using this function to get an array of single elements: 我正在使用此函数来获取单个元素的数组:

example.reduce(function (prev, curr) {
    if (prev.indexOf(curr.name) === -1) prev.push(curr.name);
    return prev;
}, []);

While this works, I try to use a ternary operator for readability like this: 在这种情况下,我尝试使用三元运算符来提高可读性,如下所示:

example.reduce(function (prev, curr) {
    return prev.indexOf(curr.name) === -1 ? prev.push(curr.name) : prev;
}, []);

and I get the following error in Chrome: 我在Chrome中收到以下错误:

Uncaught TypeError: prev.indexOf is not a function
    at <anonymous>:3:13
    at Array.reduce (native)
    at <anonymous>:2:9
    at Object.InjectedScript._evaluateOn (<anonymous>:895:140)
    at Object.InjectedScript._evaluateAndWrap (<anonymous>:828:34)
    at Object.InjectedScript.evaluate (<anonymous>:694:21)

Why is that? 这是为什么?

it is because calling .push() will return the new length of the array which is a number, so the second call prev will be a number(1) which don't have the push method. 这是因为调用.push()将返回数组的新长度,该长度是一个数字,因此第二个调用prev将是一个没有push方法的number(1)。

Returns 返回

The new length property of the object upon which the method was called. 调用该方法的对象的新length属性。

So using the if condition will be better in your case. 因此,使用if条件会更好。

If you want to still use the ternary operator, you can use a hacky solution like 如果您仍然想使用三元运算符,则可以使用诸如

var b = example.reduce(function (prev, curr) {
    return prev.indexOf(curr['name']) === -1 ? prev.push(curr['name']) && prev : prev;
}, []);

Replace your ternary operator with && and , instead of ? &&和代替您的三元运算符,而不是? and : as follows: :如下:

example.reduce(function (prev, curr) {
    return prev.indexOf(curr.name) < 0 && prev.push(curr.name), prev;
}, []);

In this case, instead of using the ternary operator we use logical AND to test whether prev.indexOf(curr.name) < 0 and if so then we do prev.push(curr.name) . 在这种情况下,我们不是使用三元运算符,而是使用逻辑AND来测试prev.indexOf(curr.name) < 0 ,如果是,那么我们进行prev.push(curr.name) However, we always return prev because of the comma operator . 但是,由于逗号运算符 ,我们总是返回prev

As I mentioned in my comment, your code doesn't work because .push doesn't return the original array. 正如我在评论中提到的那样,您的代码不起作用,因为.push不返回原始数组。 It returns the new length of the array. 它返回数组的新长度。 You could replace .push with .concat but it would be very inefficient. 您可以将.push替换为.concat但是效率很低。 The method I described above is better. 我上面描述的方法更好。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM