Terse way to intersperse element between all elements in JavaScript array?

Tags: , , ,



Say I have an array var arr = [1, 2, 3], and I want to separate each element by an element eg. var sep = "&", so the output is [1, "&", 2, "&", 3].

Another way to think about it is I want to do Array.prototype.join (arr.join(sep)) without the result being a string (because the elements and separator I am trying to use are Objects, not strings).

Is there a functional/nice/elegant way to do this in either es6/7 or lodash without something that feels clunky like:

_.flatten(arr.map((el, i) => [el, i < arr.length-1 ? sep : null])) // too complex

or

_.flatten(arr.map(el => [el, sep]).slice(0,-1) // extra sep added, memory wasted

or even

arr.reduce((prev,curr) => { prev.push(curr, sep); return prev; }, []).slice(0,-1)
// probably the best out of the three, but I have to do a map already
// and I still have the same problem as the previous two - either
// inline ternary or slice

Edit: Haskell has this function, called intersperse

Answer

Using a generator:

function *intersperse(a, delim) {
  let first = true;
  for (const x of a) {
    if (!first) yield delim;
    first = false;
    yield x;
  }
}

console.log([...intersperse(array, '&')]);

Thanks to @Bergi for pointing out the useful generalization that the input could be any iterable.

If you don’t like using generators, then

[].concat(...a.map(e => ['&', e])).slice(1)


Source: stackoverflow