Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
有没有更好的方法在JavaScript中对数组项进行部分求和?_Javascript_Arrays_Functional Programming_Prefix Sum - Fatal编程技术网

有没有更好的方法在JavaScript中对数组项进行部分求和?

有没有更好的方法在JavaScript中对数组项进行部分求和?,javascript,arrays,functional-programming,prefix-sum,Javascript,Arrays,Functional Programming,Prefix Sum,我想知道是否有更好的方法为数组的部分和生成性能更好的解 给定一个数组,比如说x=[0,1,2,3,4,5],我生成项目的子数组,然后计算每个数组的总和,得到: [ 0, 1, 3, 6, 10, 15 ] 因此,完整的代码是: x.map((y,i)=>x.filter((t,j)=>j<=i)) .map(ii=>ii.reduce((x,y)=>x+y,0)) x.map((y,i)=>x.filter((t,j)=>jii.reduce((x,y)=>x

我想知道是否有更好的方法为数组的部分和生成性能更好的解

给定一个数组,比如说
x=[0,1,2,3,4,5]
,我生成项目的子数组,然后计算每个数组的总和,得到:

[ 0, 1, 3, 6, 10, 15 ]
因此,完整的代码是:

x.map((y,i)=>x.filter((t,j)=>j<=i))
 .map(ii=>ii.reduce((x,y)=>x+y,0))
x.map((y,i)=>x.filter((t,j)=>jii.reduce((x,y)=>x+y,0))

我想知道flat map或其他一些数组方法是否有一个不需要扩展每个子数组的解决方案。

一个选项是使用单个
.map
,它使用
.reduce
来汇总切片的部分数组:

constx=[0,1,2,3,4,5];
常数和=(x,y)=>x+y;
const partialSums=x.map((u,i,arr)=>arr.slice(0,i+1).reduce(sum));

console.log(partialSums);
很多,通过保持一个运行总数:

函数*partialSums(可编辑){
设s=0;
for(iterable的常数x){
s+=x;
产量;
}
}
常数x=[0,1,2,3,4,5];

console.log(Array.from(partialSums(x)).join(“,”);
下面,
scan
使用映射函数
f
和初始累加器
r
-

const scan=(f,r,[x,…xs])=>
x==未定义
?[r]
:[r,…扫描(f,f(r,x),xs)]
常数加=(x,y)=>
x+y
常量打印=(…vs)=>
vs.forEach(v=>console.log(v))
常量数据=
[ 0, 1, 2, 3, 4, 5 ]
打印
(扫描(添加、0、数据)
,扫描(Math.max,3,数据)
,扫描(添加,0,[])
)
// [ 0, 0, 1, 3, 6, 10, 15 ]
// [ 3, 3, 3, 3, 3, 4, 5 ]

//[0]
您可以简单地使用带有变量的
for
循环来跟踪最后一次求和

设x=[0,1,2,3,4,5]
设总和=(arr)=>{
设和=0
让final=[]

对于(设i=0;i),平面图在您的情况下不会有用,因为您不会试图将部分结果作为列表进行展平,但我们可能会尝试在一个简化中解决您的问题:

它还只对数组进行一次迭代,因此与创建切片然后求和的解决方案相比,它的性能可能要高一些

或具有
阵列的版本。推送
,该版本重用相同的阵列:

[0, 1, 2, 3, 4, 5]
.reduce(
   ([arr, sum], el) => { // We pass along array and running sum
       const next = sum + el
       arr.push(next)
       return [arr, next]
   },
   [[], 0] // We need to seed our reduce with empty array and accumulator for calculating running sum
)[0] 

您只需要在每个步骤中将当前值添加到先前的结果中,这样就可以使用简单的reduce

常量数组=[0,1,2,3,4,5,6]; const sums=数组。reduce((acc、current、index)=>{ const prev=附件长度?附件[索引-1]:0; acc.push(上一个+当前); 返回acc; },[]); console.log(sums.toString());
如果您询问是否有更快或更有效的方法,那么其他答案就足够了

然而,我认为,如果我们将它表述为一个映射函数,那么类似于当前解决方案的内容更容易阅读,更具声明性

var array = [ 0, 1, 2, 3, 4, 5 ];

function sumArray(arrayToSum, index){
    if(index < arrayToSum.length-1){
        arrayToSum[index+1] = arrayToSum[index] + arrayToSum[index+1];
        return sumArray(arrayToSum, index+1);
  }else
    return arrayToSum;

}
sumArray(array, 0);

console.log(array);
特别是像“将每个值映射到自身加上数组中以前的所有值”

你可以使用一个过滤器,就像你在问题中所做的那样,但我认为一个片段更清晰

const x = [ 0, 1, 2, 3, 4, 5 ];

// A common generic helper function
const sum = (acc, val) => acc + val

const sums = x.map((val, i, self) => val + self.slice(0, i).reduce(sum, 0))

下面是一个使用递归函数的简单答案

var array = [ 0, 1, 2, 3, 4, 5 ];

function sumArray(arrayToSum, index){
    if(index < arrayToSum.length-1){
        arrayToSum[index+1] = arrayToSum[index] + arrayToSum[index+1];
        return sumArray(arrayToSum, index+1);
  }else
    return arrayToSum;

}
sumArray(array, 0);

console.log(array);
var数组=[0,1,2,3,4,5];
函数sumArray(arrayToSum,索引){
if(索引
一种方法是对每个数组使用,然后对数组进行切片,以逐个获取元素,然后通过
数组对所有元素求和。reduce
您可以这样做

设x=[0,1,2,3,4,5]
让sum=[]
x、 forEach((u,索引)=>{
索引++;
sum.push(x.slice(0,索引).reduce((a,b)=>a+b))
})

console.log(sum)
如果保留外部累加器变量,则可以直接使用map:
constx=[0,1,2,3,4,5];
设acc=0;
const prefixSum=x.map(x=>acc+=x);

log(前缀);
最简单的答案是一行:如果x是[0,1,2,3,4,5]

x.map(i=>s+=i, s=0)

顺便说一句,这称为前缀和或扫描。许多集合框架在标准库中都有它,但不幸的是ECMAScript没有。呃…
yield
是一个很弱的词。将每个项添加到数组中,然后像人一样返回它。
return
。@LogicalBranch:这不会在线,所以您最好使用第二个代码段嗯。@LogicalBranch为什么?迭代器FTW在2019年,不是吗?@LogicalBranch迭代器是做部分和的方法,如果你有一个大数组,或者你只需要一个特定的值。为什么你不喜欢收益率?我知道它不像return那样出现在你的脸上,但它描述了它在做什么。这是一个很好的命令式答案,但是,它没有这是一个带有函数式编程的问题。这只是一个特定辅助函数对一个非常特定的问题的1:1分配。零泛化,没有学到任何东西。这将同样缓慢(O(n²))因为它每次想添加一些东西时都会复制数组。@Ry-你可以很容易地用
push
替换它,但它会变异数组,这会使它不完全起作用。你有没有看过有问题的tag
函数式编程
?没有什么是完全起作用的。你拥有数组。这完全没问题。@Ry-不是真的ly,您可以使用纯函数方法。但是正如您所提到的,使用
push
的版本在引用上是透明的,所以也可以。编辑我的答案以包含第二个版本。第二个代码片段看起来非常熟悉,甚至隐藏了。@Ry-上面的行说明
您也可以使用map
,我想展示的是传统和实用的方法,如果人们觉得这是否决投票的正当理由,我很高兴:)
scan
很好。在JavaScript中像Haskell一样实现
scan
是不好的,因为它会给您带来二次时间复杂度和数组上的堆栈溢出,而这些数组甚至不是特别复杂