Предположим, мне нужен массив с несколькими повторяющимися элементами, например так:
[3,3,3,3,3,8,8,8,8,5,5,5,5,5,5]
(так что это пять 3, четыре 8 и шесть 5)
В python вы можете очень элегантно определить это так:
[3]*5+[8]*4+[5]*6
Есть ли похожие конструкции в JS или PHP?
В этом примере явное определение всего массива не является большой проблемой. Но если есть много элементов, с большим количеством повторений, это может стать очень утомительным (не говоря уже о склонности). Я хочу, чтобы размер моего кода оставался равным, независимо от того, имеет ли массив пять 3-х или пятьсот.
В 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;
Очевидно, что это не приносит бонусные баллы за удобочитаемость. Есть ли лучший способ (желательно некоторая языковая конструкция) сделать это?
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;
}
Теперь вы можете CONCAT все вместе «умноженные» массивы
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]
Если вы действительно хотите, вы можете продлить прототип из массив включить 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 "новый массив (n)" а также "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
)
Причудливый (только цифры) х-)
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);
})
);
}