Reputation: 11150
Suppose I need an array with a number of repetitive elements, like this:
[3,3,3,3,3,8,8,8,8,5,5,5,5,5,5]
(so that's five 3s, four 8s, and six 5s)
In python, you can define this very elegantly like this:
[3]*5+[8]*4+[5]*6
Are there similar constructions in JS or PHP?
In this example, defining the entire array explicitly isn't that much of a problem. But if there are many elements, with lots of repetitions, this can become very tedious (not to mention prone). I want my code size to stay equal, regardless of whether the array has five 3s or five hundred.
In JS, the shortest I can think of is:
var a = [];
[[3,5],[8,4],[5,6]].forEach(function(x){while(x[1]--)a.push(x[0])});
Similar in PHP:
foreach(array(3=>5,8=>4,5=>6) as $d=>$n) while($n--) $a[]=$d;
Obviously this doesn't score bonus points for readability. Is there a better way (preferably some language construct) to do this?
Upvotes: 1
Views: 112
Reputation: 10556
In 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()" allows to pass arguments to a function in the form of an array, roughly:
say.apply(null, ['hello', 'world'])
Is the same as:
say('hello', 'world')
Hence, since Array(3)
gives [undefined x 3]
:
Array.apply(null, Array(3))
Is the same as:
Array(undefined, undefined, undefined)
Why is it required? Refer to JavaScript "new Array(n)" and "Array.prototype.map" weirdness.
Upvotes: 1
Reputation:
A freaky one (numbers only) 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);
})
);
}
Upvotes: 0
Reputation: 66364
Array.prototype.concat
The best way for readability and re-usability is probably to define a function for Array "multiplication", for example this one does it exponentially
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;
}
Now you can concat together "multiplied" Arrays
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]
If you really want to, you can extend the prototype of Array to include the arrMultiply
function which would give you syntax closer to what you're already using,
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]
Upvotes: 1
Reputation: 59701
You can use array_fill()
to fill up an array with the values and array_merge()
it into your results array, e.g.
<?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);
?>
output:
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
)
Upvotes: 0