34

I have an array [a, b, c]. I want to be able to insert a value between each elements of this array like that: [0, a, 0, b, 0, c, 0].

I guess it would be something like this, but I can't make it works.

for (let i = 0; i < array.length; i++) {
    newArray = [
        ...array.splice(0, i),
        0,
        ...array.splice(i, array.length),
    ];
}

Thank you for helping me!

Peter Huber
  • 3,052
  • 2
  • 30
  • 42
Philippe
  • 960
  • 2
  • 12
  • 29
  • would you like to get a new array or insert in the given array? – Nina Scholz Oct 02 '17 at 15:26
  • @NinaScholz if it could be inserted in the current array it will be better – Philippe Oct 02 '17 at 15:28
  • 1
    I think you're confusing `slice` with `splice`. My answer shows how you can use `splice` to accomplish this by inserting into the original array. – JLRishe Oct 02 '17 at 15:35
  • Does this answer your question? [What is the most elegant way to insert objects between array elements?](https://stackoverflow.com/questions/31879576/what-is-the-most-elegant-way-to-insert-objects-between-array-elements) – programmerRaj Mar 23 '21 at 18:00

20 Answers20

27

For getting a new array, you could concat the part an add a zero element for each element.

var array = ['a', 'b', 'c'],
    result = array.reduce((r, a) => r.concat(a, 0), [0]);
    
console.log(result);

Using the same array

var array = ['a', 'b', 'c'],
    i = 0;

while (i <= array.length) {
    array.splice(i, 0, 0);
    i += 2;
}

console.log(array);

A bit shorter with iterating from the end.

var array = ['a', 'b', 'c'],
    i = array.length;

do {
    array.splice(i, 0, 0);
} while (i--)

console.log(array);
Nina Scholz
  • 376,160
  • 25
  • 347
  • 392
17

Another way if you want to exclude the start and end of array is :

var arr = ['a', 'b', 'c']
var newArr = [...arr].map((e, i) => i < arr.length - 1 ? [e, 0] : [e]).reduce((a, b) => a.concat(b))

console.log(newArr)
Vincent Menant
  • 477
  • 4
  • 10
9

You can use map() with ES6 spread syntax and concat()

var arr = ['a', 'b', 'c']
var newArr = [0].concat(...arr.map(e => [e, 0]))

console.log(newArr)
Nenad Vracar
  • 118,580
  • 15
  • 151
  • 176
7

Another ES6+ version using flatmap (if creation of a new array instead is ok):

['a', 'b', 'c', 'd']
    .flatMap((e, index) => index ? [e, 0] : [0, e, 0])
Sebastian Barth
  • 4,079
  • 7
  • 40
  • 59
4

Another way:

var a = ['a', 'b', 'c'],
  b;

b = a.reduce((arr, b) => [...arr, b, 0], []);

console.log(b);
Pako Navarro
  • 168
  • 1
  • 2
  • 9
3

You could use .reduce():

function intersperse(arr, val) {
  return arr.reduce((acc, next) => {
    acc.push(next);
    acc.push(val);
    return acc;
  }, [val]);
}

console.log(intersperse(['a', 'b', 'c'], 0));

Or to accomplish this by modifying the original array:

function intersperse(arr, val) {
  for (let i = 0; i <= arr.length; i += 2) {
    arr.splice(i, 0, val);
  }

  return arr;
}

console.log(intersperse(['a', 'b', 'c'], 0));
JLRishe
  • 99,490
  • 19
  • 131
  • 169
2

You can try with the below code. It will add 0 in middle of each two element of the array

console.log(['a', 'b', 'c'].reduce((r, a) => r.concat(a,0), [0]).slice(1, -1))
Alok
  • 297
  • 3
  • 13
  • I'm curious as to why you initialize the value of `r` with a `0` in it, only to slice it off later? Why not `.reduce((r, a) => r.concat(a,0), []).slice(0, -1)`? – JAAulde Aug 11 '21 at 18:39
1

You just need to loop over the array elements and add the new element in each iteration, and if you reach the last iteration add the new element after the last item.

This is how should be your code:

var arr = ['a', 'b', 'c'];
var results = [];
arr.forEach(function(el, index) {
  results.push(addition);
  results.push(el);
  if (index === arr.length - 1)
        results.push(addition);
});

Demo:

This is a Demo snippet:

var arr = ['a', 'b', 'c'];
var results = [];
var addition = 0;
arr.forEach(function(el, index) {
  results.push(addition);
  results.push(el);
  if(index === arr.length -1)
        results.push(addition);
});
console.log(results);
cнŝdk
  • 31,391
  • 7
  • 56
  • 78
1

If you want to insert elements only after existing ones:

console.log(["a", "b", "c"].map(i => [i, 0]).flat())
snazzybouche
  • 2,241
  • 3
  • 21
  • 51
0

You could do

let arr = ['a', 'b', 'c'];

arr = arr.reduce((a, b) => {
    a.push(0);
    a.push(b);
    return a;
}, []);
arr.push(0);
console.log(arr);
marvel308
  • 10,288
  • 1
  • 21
  • 32
0

function insert(arr, elm) {
  var newArr = [];
  for(var i = 0; i < arr.length; i++) {   // for each element in the array arr
    newArr.push(elm);                     // add the new element to newArr
    newArr.push(arr[i]);                  // add the current element from arr
  }
  newArr.push(elm);                       // finally add the new element to the end of newArr
  return newArr;
}

console.log(insert(["a", "b", "c"], 0));
ibrahim mahrir
  • 31,174
  • 5
  • 48
  • 73
0

It could be done with strings by splitting and joining.

var arr = ['a', 'b', 'c'];
var newArray = ("0," + arr.toString().split(",").join(",0,")).split(",");
console.log(newArray);
0

This looks like the intersperse algorithm but does some addition to the head and tail as well. So i call it extrasperse.

var arr         = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9],
    extrasperse = (x,a) => a.reduce((p,c,i) => (p[2*i+1] = c, p), Array(2*a.length+1).fill(x));

console.log(JSON.stringify(extrasperse("X",arr)));
Redu
  • 25,060
  • 6
  • 56
  • 76
0

let arr = ['a', 'b', 'c'];

function insert(items, separator) {
  const result = items.reduce(
    (res, el) => [...res, el, separator], [separator]);
  return result;
}

console.log(insert(arr, '0'));
Yangshun Tay
  • 49,270
  • 33
  • 114
  • 141
0

all of the above methods in very long strings made my android computer run on React Native go out of memory. I got it to work with this

let arr = ['a', 'b', 'c'];
let tmpArr = [];

for (const item in arr) {
  tmpArr.push(item);
  tmpArr.push(0);
}

console.log(tmpArr);
x-magix
  • 2,623
  • 15
  • 19
0

Another way is to use some functional methods like zip and flat. Check out lodash.

const array = ['a', 'b', 'c']
const zeros = Array(array.length + 1).fill(0)
const result = _.zip(zeros, array).flat().filter(x => x !== undefined)
console.log(result)
<script src="https://cdn.jsdelivr.net/npm/lodash@4.17.15/lodash.min.js"></script>
Mengo
  • 1,177
  • 1
  • 10
  • 25
0

Straight forward way of inserting only between:

const arr = ['a', 'b', 'c'];

arr.map((v, i) => !i || i === arr.length - 1 ? [v] : [0, v]).flat() 
Gabriel Petersson
  • 8,434
  • 4
  • 32
  • 41
0

I think this is correct, ie, just adds the element between the elements of the array, and should be pretty efficient:

const intersperse = ([first, ...tail]: any[], element: any) => (
    (first === undefined) ? [] : [first].concat(...tail.map((e) => [element, e]))
);

console.log(intersperse([], 0));
console.log(intersperse([1], 0));
console.log(intersperse([1, 2, 3], 0));
Ben Golding
  • 726
  • 6
  • 8
0

Thanks for your question and thanks to all contributors, for their answers. This would be my approach

const arr = ["a", "b", "c"];
let toAdd = 0;
for (let i = 0; i <= arr.length; i += 2) {
  arr.splice(i, 0, toAdd);
}
console.log(arr);

or

const arr = ["a", "b", "c"];
let toAdd = 0;
const newArr = [];
newArr.unshift(toAdd);
for (let i = 0; i < arr.length; i++) {
  newArr.push(arr[i]);
  newArr.push(toAdd);
}
console.log(newArr);

Cheers Nav

Nav
  • 71
  • 9
0

A fast solution not in-place: (based on my >10x flatMap (similar use-case))

function arrayJoin(inp, sep) {
  let tar = new Array(inp.length * 2 + 1)
  for (let i = inp.length - 1; i > -1; --i) {
    tar[i * 2 + 1] = inp[i]
    tar[i * 2] = sep
  }
  tar[inp.length * 2] = sep
  return tar
}

// Verify
let inp = arrayJoin(["a", "b", "c"], 0)
console.log(inp.join(" "))

If you need modification (in-place) use the while {splice} approach

Simon
  • 1,172
  • 12
  • 21