Самый эффективный (компактный) способ создания повторяющихся массивов в JavaScript или PHP?

Предположим, мне нужен массив с несколькими повторяющимися элементами, например так:

[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;

Очевидно, что это не приносит бонусные баллы за удобочитаемость. Есть ли лучший способ (желательно некоторая языковая конструкция) сделать это?

1

Решение

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;
}

Теперь вы можете 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]
1

Другие решения

В 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" странность.

1

Ты можешь использовать 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
)
0

Причудливый (только цифры) х-)

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);
})
);
}
0
По вопросам рекламы [email protected]