我刚刚了解了MapReduce,所以我想知道写作是否有任何优势
const initialValue = 0;
if (this.items) {
return this.items.filter(function (item) {
return item && item.quantity && item.price;
}).reduce(function(previousValue, currentValue) {
return previousValue + currentValue.quantity * currentValue.price ;
}, initialValue);
} else {
return initialValue;
}
而不仅仅是
let total = 0;
if (this.items) {
this.items.forEach(function(item) {
if (item && item.quantity && item.price) {
total += item.quantity * item.price;
}
});
}
return total;
对于未来的读者,有一些更惯用的方法可以用函数的方式编写缩减。通常使用它们,因为它们更清晰地传达意图(并且不会向范围添加变量)。
注意:我假设this.items
有类型
({ quantity: number; price: number } | undefined)[] | undefined
但是每个示例都容忍比问题中的两个示例更多的无效数据。
减少前的过滤和映射
末尾的默认值
return this.items
?.filter(item => item?.quantity && item.price)
.map(item => item.quantity * item.price)
.reduce((a, b) => a + b, 0) ?? 0
开头的默认数组
return (this.items ?? [])
.filter(item => item?.quantity && item.price)
.map(item => item.quantity * item.price)
.reduce((a, b) => a + b, 0)
处理地图中的过滤器
我不会仅仅因为前两个更清楚地传达意图而推荐这些。
末尾的默认值
return this.items
?.map(item => (item?.quantity ?? 0) * (item?.price ?? 0))
.reduce((a, b) => a + b, 0) ?? 0
开头的默认数组
return (this.items ?? [])
.map(item => (item?.quantity ?? 0) * (item?.price ?? 0))
.reduce((a, b) => a + b, 0)
解构
前面的每个示例都可以通过解构来完成。我举一个例子。
return (this.items ?? [])
.filter(item => item) // Ensure item exists; sufficient for the cases we need to worry about
.map(({ price = 0, quantity = 0 }) => quantity * price)
.reduce((a, b) => a + b, 0)
没有地图
我们现在可以在没有地图的情况下进行缩减。这也可以在不解构的情况下完成,但这似乎(对我来说)不优雅。
return (this.items ?? [])
.filter(item => item)
.reduce((sum, { price = 0, quantity = 0 }) => sum + quantity * price, 0)
当然,您可以更改筛选条件,这将我们带回问题中大致的第一个示例:
return (this.items ?? [])
.filter(item => item?.price && item.quantity)
.reduce((sum, { price, quantity }) => sum + quantity * price, 0)
原始forEach
循环
其中一些更改也可以对原始循环进行:
let total = 0;
items?.forEach((item) => {
if (item?.quantity && item.price) {
total += item.quantity * item.price;
}
});
return total;
我看不出第一个比第二个*有任何优势。然而,第二个甚至比第一个更快,看起来更干净!第一个的目的可能是演示内置数组函数的使用。
然而,mapreduce用于很多元素,所以你可以尽可能地加快它。这应该是你能得到的最快的:
const initialValue = 0;
let total = initialValue;
if (this.items) {
for (var i = this.items.length; i--;) {
let item = this.items[i]
if (item && item.quantity && item.price) {
total += item.quantity * item.price;
}
}
return total;
} else {
return initialValue
}
此外,如果您知道数组是连续的,则可以将if
放在循环中。这两个if
都只是为了确保正确构建数组并且脚本不会遇到错误,这对于用户数据输入很有用,但在封闭系统中您不需要它们。
*我注意到,第二个缺少默认值return initialValue
让我们首先使用下面给出的代码来了解 forEach:
let arr = [2,3,4,5,6];
arr.forEach((value,index,array) => {
console.log(value,index,array);
})
在上面的代码中,我们使用了 for Each 循环,我们可以在其中给出值、索引、数组等参数——这将返回该值和完整数组的值和索引。
让我们了解地图中的地图,它将创建一个新数组并返回该数组
let a = arr.map((value , index ,array)=>{
console.log(value , index,array);
return value + 1;
})
console.log(a);
In this you can return the values or change as per you preference like return value*10 or return value + 1;
让我们了解过滤器中的过滤器,它将创建一个新数组并返回该数组
let arr2 = [42,3,1,45,5,55];
let a2 = arr2.filter((value)=>{
return value < 10;
})
console.log(a2);
In this we can give some condition like return value>10 or return value < 10 ans many more
在reduce方法中,它将通过计算函数返回单个值
let arr3 = [1,2,3,5,2,1];
let newarr3 = arr3.reduce((val1,val2) => {
return val1+val2;
})
console.log(newarr3);
在上面的代码中,首先是 val1=1,val2=2,然后它们的总和为 3 而不是 val1=3,val2= 是 5,因此它将汇总数组中的所有元素并返回 ans 为 14。
重要 - 映射,过滤器,减少不会更改您现有的数组!!