在这种情况下如何摆脱中间阵列?

时间:2018-09-12 08:58:46

标签: javascript

我有这个功能(我认为代码是不言自明的):

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的更短方法吗?

4 个答案:

答案 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: ...}对象。

这可以通过组合filtermap来完成:

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;
}