我有这个功能(我认为代码是不言自明的):
items: function(input) {
let arr = [];
for(let i=0; i<input.length; i++){
if(input[i].quantity > 0) {
arr.push({
value: false,
name: input[i].name,
});
}
}
return arr;
},
我想知道是否有一种不依赖中间arr
的更短方法吗?
答案 0 :(得分:5)
我将使用内置的Array方法:
items: (input) => input
.filter(({ quantity }) => quantity > 0)
.map(({ name }) => ({ name, value: false }))
答案 1 :(得分:1)
无论如何(毕竟需要返回某些内容),您都将创建,但是一个选择是立即返回对reduce
的调用:
items: input => input.reduce((a, { name, quantity }) => {
if (quantity > 0) a.push({ value: false, name });
return a;
}, []))
这类似于在.filter
之后加上.map
可以完成的操作,但是在.filter
之后加上.map
则需要不必要的中间数组构造,并且需要对某些输入元素进行两次迭代,而不是一次。
答案 2 :(得分:1)
您的代码结合了过滤和转换。您只想保留quantity
为正的元素,并且要将其转换为{value: false, name: ...}
对象。
这可以通过组合filter
和map
来完成:
items: function(input) {
return (
input
.filter(function (x) { return x.quantity > 0; })
.map(function(x) { return { value: false, name: x.name }; })
);
}
您可以使用reduce
融合这两种操作:
items: function(input) {
return (
input
.reduce(function (z, x) {
return (
x.quantity > 0
? z.concat({value: false, name: x.name})
: z
);
}, [])
);
}
这仅遍历input
一次,但是构造了许多中间数组(通过concat
)。
您可以通过编写命令式循环来“作弊”,该命令式就地修改累加器数组(例如arr
),但将其伪装成reduce
:
items: function(input) {
return (
input
.reduce(function (arr, x) {
if (x.quantity > 0) {
arr.push({value: false, name: x.name});
}
return arr;
}, [])
);
}
这里我们仍然有一个中间arr
,但其定义在末尾的function (arr, x)
,return arr
和[]
之间隐藏/分布。
它在功能上等同于:
items: function(input) {
var arr = []; // used to be function (arr, ...) ..., []
input.reduce(function (_, x) {
if (x.quantity > 0) {
arr.push({value: false, name: x.name});
}
}, undefined);
return arr; // used to be inside the reduce call
}
实际上仅使用reduce
来迭代输入元素,因此可以写为
items: function(input) {
var arr = [];
input.forEach(function (x) {
if (x.quantity > 0) {
arr.push({value: false, name: x.name});
}
});
return arr;
}
几乎是您的原始代码。
答案 3 :(得分:0)
您将需要一个数组来存储返回的对象。您的代码可以改写为:
items: input => {
const a = input.map(i => {
if (i.quantity > 0) {
return {name: i.name, value: false};
}
})
return a;
}