假设我需要一个包含许多重复元素的数组,如下所示:
[3,3,3,3,3,8,8,8,8,5,5,5,5,5,5]
(5个3,4个8,6个5)
在python中,你可以像这样优雅地定义:
[3]*5+[8]*4+[5]*6
是否有类似的结构在JS或PHP?
在本例中,显式定义整个数组并不是什么大问题。但如果有很多元素,有很多重复,这就会变得非常乏味(更不用说容易了)。我希望我的代码大小保持不变,不管数组是5个3还是500个。
在JS中,我能想到的最短是:
var a = [];
[[3,5],[8,4],[5,6]].forEach(function(x){while(x[1]--)a.push(x[0])});
类似于PHP:
foreach(array(3=>5,8=>4,5=>6) as $d=>$n) while($n--) $a[]=$d;
显然这不会为可读性加分。是否有更好的方法(最好是某种语言结构)来做到这一点?
JavaScript
-
数组"加法"通过
Array.prototype.concat
完成 - 没有原生数组"乘法"
function arrMultiply(arr, i) {
var arr_out = [];
if (i & 1)
arr_out = arr_out.concat(arr);
while ((i >>>= 1) > 0) {
arr = arr.concat(arr);
if (i & 1)
arr_out = arr_out.concat(arr);
}
return arr_out;
}
现在你可以将" multiply "数组
arrMultiply([3], 5).concat(arrMultiply([8], 4)).concat(arrMultiply([5], 6));
// [3, 3, 3, 3, 3, 8, 8, 8, 8, 5, 5, 5, 5, 5, 5]
如果你真的想,你可以扩展Array的原型来包含arrMultiply
函数,这会给你更接近你已经使用的语法,
Array.prototype.mul = function (i) {return arrMultiply(this, i);};
[3].mul(5).concat([8].mul(4)).concat([5].mul(6));
// [3, 3, 3, 3, 3, 8, 8, 8, 8, 5, 5, 5, 5, 5, 5]
JavaScript中:
Array.apply(null, Array(c)).map(function () {
return v;
});
function f(c, v) {
return Array.apply(null, Array(c)).map(function () {
return v;
});
}
document.write(f(5, 3).concat(f(4, 8)).concat(f(6, 5)));
".apply()"允许以数组的形式向函数传递参数,大致如下:
say.apply(null, ['hello', 'world'])
等于:
say('hello', 'world')
因此,既然Array(3)
给出[undefined x 3]
:
Array.apply(null, Array(3))
等于:
Array(undefined, undefined, undefined)
为什么是必需的?参考JavaScript "new Array(n)"answers";Array.prototype.map"不可思议。
你可以使用array_fill()
填充一个数组的值和array_merge()
它到你的结果数组,例如
<?php
$arr = [[3,5],[8,4],[5,6]];
$result = [];
foreach($arr as $v)
$result = array_merge($result, array_fill(0, $v[1], $v[0]));
print_r($result);
?>
输出:Array
(
[0] => 3
[1] => 3
[2] => 3
[3] => 3
[4] => 3
[5] => 8
[6] => 8
[7] => 8
[8] => 8
[9] => 5
[10] => 5
[11] => 5
[12] => 5
[13] => 5
[14] => 5
)
一个怪异的(仅限数字)x-)
document.write(
'<pre>' + JSON.stringify(
makeArray('[1x1,3x4,42x3]')
) + '</pre>'
);
function makeArray (expr) {
return JSON.parse(
expr.replace(/('d+)x('d+)/g, function ($0, $1, $2) {
return $1 + new Array(+$2).join(','+$1);
})
);
}