在JavaScript数组中所有元素之间穿插元素的方法是什么?

Aar*_*n_H 18 javascript arrays ecmascript-6 lodash

假设我有一个数组var arr = [1, 2, 3],我想用元素分隔每个元素,例如.var sep = "&",所以输出是[1, "&", 2, "&", 3].

考虑它的另一种方法是我想做Array.prototype.join(arr.join(sep))而不是结果是一个字符串(因为我试图使用的元素和分隔符是对象,而不是字符串).

有没有一种功能性/漂亮/优雅的方式来做es6/7或lodash没有像笨重的东西:

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

要么

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

甚至

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
Run Code Online (Sandbox Code Playgroud)

编辑:Haskell有这个功能,称为intersperse

小智 17

使用发电机:

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

console.log([...intersperse(array, '&')]);
Run Code Online (Sandbox Code Playgroud)

感谢@Bergi指出输入可以是任何可迭代的有用概括.

如果你不喜欢使用发电机,那么

[].concat(...a.map(e => ['&', e])).slice(1)
Run Code Online (Sandbox Code Playgroud)

  • [`flatMap`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/flatMap) 使这变得更加容易:`a.flatMap(e =&gt; ['&amp; ', e]).slice(1)` (3认同)

Kla*_*r_1 8

减少函数的传播和显式返回将使其更简洁:

const intersperse = (arr, sep) => arr.reduce((a,v)=>[...a,v,sep],[]).slice(0,-1)
// intersperse([1,2,3], 'z')
// [1, "z", 2, "z", 3]
Run Code Online (Sandbox Code Playgroud)


Ber*_*rgi 7

在 ES6 中,您将编写一个生成器函数,该函数可以生成一个迭代器,该迭代器生成带有散布元素的输入:

function* intersperse(iterable, separator) {
    const iterator = iterable[Symbol.iterator]();
    const first = iterator.next();
    if (first.done) return;
    else yield first.value;
    for (const value of iterator) {
        yield separator;
        yield value;
    }
}

console.log(Array.from(intersperse([1, 2, 3], "&")));
Run Code Online (Sandbox Code Playgroud)

  • 或 `yield *[separator, value]` :-) (3认同)

Red*_*edu 5

一种直接的方法可能是向reduce 函数提供一个初始数组,该数组的大小比原始数组的两倍小一号,并填充用于穿插的字符。然后将原始数组的索引 i 处的元素映射到最初馈送的目标数组中的 2*i 将完美地完成这项工作..

在这种方法中,我看不到 (m) 任何冗余操作。此外,由于我们在设置后没有修改任何数组大小,因此我不希望任何后台任务运行以进行内存重新分配、优化等。另一个好的部分是使用标准数组方法,因为它们会检查各种不匹配什么的。

此函数返回一个新数组,其中被调用的数组项与提供的参数散布在一起。

var arr = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
Array.prototype.intersperse = function(s){
  return this.reduce((p,c,i) => (p[2*i]=c,p), new Array(2*this.length-1).fill(s));
}
document.write("<pre>" + JSON.stringify(arr.intersperse("&")) + "</pre>");
Run Code Online (Sandbox Code Playgroud)