20

I have this javascript:

function padded_array(k, value){
    var a = [];
    a[k] = value;
    return a;
}

padded_array(3, "hello"); //=> [undefined, undefined, undefined, 'hello']

Is it possible to shorten the code in the function body?

maček
  • 76,434
  • 37
  • 167
  • 198

10 Answers10

43

for all the googlers coming here - you're probably looking for this:

var pad_array = function(arr,len,fill) {
  return arr.concat(Array(len).fill(fill)).slice(0,len);
}
k0m0r
  • 451
  • 4
  • 3
  • 7
    This version saves a little memory: `function padArray(array, length, fill) { return length > array.length ? array.concat(Array(length - array.length).fill(fill)) : array; }` – Zack Morris Apr 21 '18 at 00:38
  • 2
    If you need left padding as I did, this does the trick `var pad_array_left = function(arr,len,fill) { return Array(len).fill(fill).concat(arr).slice( arr.length); }` – JuroOravec Feb 26 '20 at 14:48
  • I don't think that is correct @JuroOravec. I fixed it with `Array(len).fill(fill).concat(arr).slice(-(Math.max(len, arr.length)))` – Pyrolistical Dec 15 '21 at 21:14
  • Had to run both of them to see what the error was. For future readers, use @Pyrolistical's solution. Mine didn't work with arrays longer than `len` (larger arrays were shortened to `len`). – JuroOravec Dec 17 '21 at 22:33
28

From 2020 & 2021 : straight forward options

Let assume that is your Array

const yourArray = [1,2]

If you just want to loop 4 times (maybe for react jsx )

Array.from({length:4}) //[undefined,undefined,undefined,undefined]
Array(4).fill()//[undefined,undefined,undefined,undefined]

If you want to loop yourArray 4 times, but to start with values you already have

// unmutation option
Array.from({...yourArray, length:4}) //[1,2,undefined,undefined]

// unmutation option, but need some calcualtion
[...yourArray , ...Array(2)  ] //[1,2,undefined,undefined]
[...Array(2), ...yourArray   ] //[undefined,undefined,1,2]

// loop on your array several times 
Array(3).fill(yourArray).flat() // [1, 2, 1, 2, 1, 2]

// mutation the original array.
yourArray.length = 4;
Array.from(yourArray) //[1,2,undefined,undefined]

If You actually want an Array with full of values. ex. with increment numbers.
Remap it

// unmutation option

Array.from({...yourArray,length:4}, (v,i) => v ?? i+1 ) 
// [1,'2',3, 4]

// Or, mutation the original array. and fill with "x"
array.yourArray.length = 4;

Array.from(yourArray, (v) => v ?? 'x') 
// [1,'2','x','x'] 
pery mimon
  • 7,713
  • 6
  • 52
  • 57
7

If you want to exclude the 'hello', you can use

new Array(count);

to create padded Arrays.

Edit: Maybe like this ?

new Array(5).concat("hello")

copy
  • 3,301
  • 2
  • 29
  • 36
  • This is far and away just the simplest, most readable, most intuitive solution. Just make an array using the native constructor (which is optimized), stick your value(s) on the end. Simple. If you need a value in each of those slots, use Array.fill(). – dudewad Sep 13 '21 at 20:33
3

Another solution using spread operator:

padArray = (length, value) => [...Array(length).fill(), value];

And the usage is the same as you mentioned:

padded_array(3, "hello"); //=> [undefined, undefined, undefined, 'hello']
3

For padding at the start:

function padArrayStart(arr, len, padding){
   return Array(len - arr.length).fill(padding).concat(arr);
}

Demo:

function padArrayStart(arr, len, padding){
   return Array(len - arr.length).fill(padding).concat(arr);
}
console.log(...padArrayStart([1,2,3], 5, 0));//0 0 1 2 3
console.log(...padArrayStart([4,5,6], 3, 0));//4 5 6

For padding at the end:

function padArrayEnd(arr, len, padding){
   return arr.concat(Array(len - arr.length).fill(padding));
}

Demo:

function padArrayEnd(arr, len, padding){
   return arr.concat(Array(len - arr.length).fill(padding));
}
console.log(...padArrayEnd(['a','b','c'], 10, 'z'));//a b c z z z z z z z
console.log(...padArrayEnd([0, 'a', 'd'], 6, -1));//0 a d -1 -1 -1
Unmitigated
  • 76,500
  • 11
  • 62
  • 80
1

Not in standard ES5 or predecessor. Surely you can do something like $.extend([], {"3": "hello"}) in jQuery; you can even do

Object.create(Array.prototype, {"3": {value: "hello"} });

in bare ES5, but it is hack, I would not consider this a solution (if it is ok with you, you can adopt it).

0

You can use that if your JS doesn't support Array.prototype.fill() (ex. Google Apps Script) and you can't use the code from the first answer:

function array_pad(array, length, filler)
{
    if(array.length < length)// [10.02.20] Fixed error that Dimitry K noticed
      while(true)
        if(array.push(filler) >= length)
          break;
    return array;
}
FLighter
  • 389
  • 1
  • 4
  • 17
  • -1 : this version of array_pad always pushes filler, even if array is already of the desired length. I was lazy and stupid enough to copy-paste this without looking carefully and faced consequences a month later... – Dimitry K Feb 06 '20 at 22:22
0

I know this is an old(er) question but wanted to add my 2 cents if someone stumbles here (like i initially did).

Anyway, heres my take with Array.from

const padded_array = (k, value) => Array.from({ length: k }).concat(value)

console.log(padded_array(3, "hello"));

Also you could do it with something like this:

const padded = (arr, pad, val) => {
  arr[pad] = val
  return arr
}

console.log(padded([],3,'hello'))
VilleKoo
  • 2,827
  • 2
  • 14
  • 23
0
// push is faster than concat
// mutate array in place + return array

const pad_right = (a, l, f) =>
  !Array.from({length: l - a.length})
  .map(_ => a.push(f)) || a;

const a = [1, 2];

pad_right(a, 4, 'x');
// -> [ 1, 2, 'x', 'x' ]

a;
// -> [ 1, 2, 'x', 'x' ]
milahu
  • 2,447
  • 1
  • 18
  • 25
0
function leftPad(array, desiredLength, padding) {
  array.unshift(...Array(desiredLength - array.length).fill(padding));
}

function rightPad(array, desiredLength, padding) {
  array.push(...Array(desiredLength - array.length).fill(padding));
}

const myHello = ['hello'];
leftPad(myHello, 3, undefined);
// [undefined, undefined, 'hello']
const myHello2 = ['hello2'];
rightPad(myHello, 3, 0);
// ['hello2', 0, 0];
Rene Juuse
  • 575
  • 8
  • 16