在JavaScript中,如何将数组中的每个元素乘以一个标量?

44
例如,我如何实现以下操作,而不需要对数组进行迭代
var a = [1, 2, 3] * 5;  // a should equal [5, 10, 15]

3
你将始终迭代数组,但如果不想显式地这样做,你总是可以使用数组对象上的map方法。尽管如此,它并不兼容所有浏览器。https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/map - bennedich
1
你可以使用underscore.js - 它有一个map函数可以为你完成这个操作 :) 否则,即使你自己编写实现,你也必须以某种方式循环它。 - PhD
1
标量:单个数字(用于处理向量或矩阵时)。 - nCardot
10个回答

46

Array.map() 从IE9起就能够使用了,所以如果您不在意兼容性问题,可以直接使用该方法:

var a = [1, 2, 3].map(function(x) { return x * 5; });

对于 JavaScript 1.8,这是你能做到的最短形式:

var a = [1, 2, 3].map(function(x) x * 5);
如果你需要最大化浏览器兼容性,那么你将不得不接受循环的存在。 无论哪种方式,你都将遍历数组;Array.map()只是让这个过程不那么明显。

1
感谢您解释浏览器兼容性的权衡。 - stephjang
3
请注意,JavaScript 1.8的语法是非标准的,除了Mozilla之外,不太可能被其他人采用。Harmony可能会包含一些lambda语法,但目前还没有决定要包含什么(尽管JS 1.8已经被排除在外)。 - gsnedders
还要注意,使用.map会多出一个数组分配。 - user993683
7
ES6 - var a = [1, 2, 3].map(x => x * 5) ES6 - var a = [1, 2, 3].map(x => x * 5) - Dhiraj Barnwal

37
在ECMAScript 6中,您可以使用箭头函数
var a = [1, 2, 3];
var b = a.map(x => x * 5); // <-------

console.log(b);   // [5, 10, 15]

箭头函数是具有词法绑定的内联函数的语法糖:
// ES6
let array2 = array1.map(x => x * 5);

// ES5
var array2 = array1.map((function (x) { return x * 5; }).bind(this));

因此,如果你需要支持Internet Explorer或其他旧浏览器(Edge能理解ES6),你可以在项目中使用babeljsTypeScript将你的代码交叉编译为ES5语法。

17
for(var i=0; i<a.length; i++) {
    a[i] *= 5;
}

1
唉,这是唯一的方法吗?太糟糕了。 - stephjang
1
@stchangg:为了兼容性,是的。 - BoltClock
3
@stchangg - 为什么这个很糟糕?这是编程 :) - PhD
不应该在数组中使用for (i in array),因为它会在迭代中包括对象的属性,而这些属性实际上并不是数组中的元素 - 它是用于迭代属性的,而不仅仅是数组元素。它在某些情况下可能有效,但会引发问题。 - jfriend00
2
@Nupul 我猜是因为我习惯了使用MATLAB后更多的数组支持。虽然其他语言如Python和Ruby似乎也没有这个功能,但它们的迭代语法更加简洁。此外,Javascript似乎只有较少的内置功能。我的意思是,令人惊讶的是,Javascript默认情况下没有字符串插值函数 - stephjang
@stchangg - 如果想要非常简洁的代码,可以使用以下代码:for (var i=0; i < a.length; a[i++]*=5); - nnnnnn

5
Ecmascript 2016(ES7)定义了SIMD数学,可以更快、更容易地进行像您所需的乘法运算。然而,目前只有Firefox夜间版本支持SIMD,浏览器支持非常有限[1],[2]。以下是它的样子:
var a = SIMD.Float32x4(1, 2, 3);
var b = SIMD.Float32x4(5, 5, 5);
SIMD.Float32x4.mul(a, b);  // Float32x4[5, 10, 15]

在广泛支持SIMD之前,您需要使用map来解决问题。

var a = [1, 2, 3].map(function(x) { return x * 5; });

这在所有现代浏览器中都得到了很好的支持 [3]。


1
对于从谷歌“未来”到这里的所有人,SIMD已从ES2016标准中删除,并在WebAssembly中完成了相关工作。没有现代浏览器支持纯JavaScript实现此功能。 - Leon Adler

3

文档所述:

map() 方法会根据提供的函数,对调用数组的每个元素进行处理,并返回一个新数组。

在我看来,如果有人想要基于当前数组的输入值创建一个新数组,则更适合使用 .map()

然而,如果有人想要就地修改数组,则使用 .forEach() 似乎更好。

在 ES6 中,我们可以使用:

以下代码将就地修改给定数组 arr(而不创建新数组):

arr.forEach((value, index) => {arr[index] *= 5});

演示:

var arr = [1, 2, 3];
var scalar = 5;

arr.forEach((value, index) => {
    arr[index] *= scalar;
});
console.log(arr);


2
您可以使用 .map,但您还需要创建一个新变量来存储新值:
var a = [1,2,3];

var b = a.map(function(x){
    return x * 5;
});

alert(b);

1
var a, i, ii, term;

a = [1,2,3];
term = 5;

for (i=0, ii=a.length; i<ii; i++) {
  a[i] = a[i] * term;
}

1
你可以尝试这个:
function scalarMultiply(arr, multiplier) {
   for (var i = 0; i < arr.length; i++)
   {
      arr[i] *= multiplier;
   }
   return arr;
}

使用方法

var a = scalarMultiply([1, 2, 3], 5);

0
使用 Lodash 的 map 函数,这将返回原始数组 a 乘以常量 5
_.map(a, function multiply(x) { return x * 5; });

0

我认为没有迭代是不可能的。

有了迭代,以下是方法:

let a=[1,2,3,4] 

然后,

方法 1:

a=a.map(e=>{return e*5})

方法二:

a.forEach((e,i)=>a[i]=5*e)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接