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)
减少函数的传播和显式返回将使其更简洁:
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)
在 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)
一种直接的方法可能是向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)