Javascript 将阵列序列与阵列细节(“点缀”)连接起来

Javascript 将阵列序列与阵列细节(“点缀”)连接起来,javascript,arrays,lodash,Javascript,Arrays,Lodash,是否有一个函数可以让我连接多个数组,并在它们之间使用分隔符(分隔符也是数组),类似于join的工作方式,但不限于字符串 该函数可以是标准JS,也可以是主要库的一部分,例如lodash(这就是为什么它在标记中被引用的原因) 下面是一个用法示例: let numbers = [[1], [2], [3]]; let result = _.joinArrays(numbers, [0]); console.log(result); //printed: [1, 0, 2, 0, 3] 这类似于:

是否有一个函数可以让我连接多个数组,并在它们之间使用分隔符(分隔符也是数组),类似于
join
的工作方式,但不限于字符串

该函数可以是标准JS,也可以是主要库的一部分,例如
lodash
(这就是为什么它在标记中被引用的原因)

下面是一个用法示例:

let numbers = [[1], [2], [3]];
let result = _.joinArrays(numbers, [0]);
console.log(result); 
//printed: [1, 0, 2, 0, 3]
这类似于:

let strings = ["a", "b", "c"];
let result = strings.join(",");
console.log(result);
//printed: "a,b,c";
但是,
join
无法使用,因为它将值转换为字符串,我不希望发生这种情况

但它适用于任何类型

这是完整的月份。发疯吧。
var编号=[
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]
],
分隔符=[
“,”,“-”,“x”
];
//矩阵穿插,分隔符变成数字的子元素
//矩阵的秩/阶/值可以是任意且可变的
数字。forEach((x,i)=>{

对于(var j=1,l=x.length;j您可以简单地使用
array.reduce
对数组进行压缩,并推送您想要用作分隔符的内容

let number=[[1]、[2]、[3];
设n=number.reduce((a,b)=>a.concat(0,b))
log(n)
您可以使用并返回一个包含项的数组,并在必要时使用胶水

constjoin=(array,glue)=>array.reduce((a,b)=>a.concat(glue,b));
变量数=[[1]、[2]、[3];
log(join(数字[0]);
log(join(编号[42,43]);
console.log(join([[1]],[0]);

.as console wrapper{max height:100%!important;top:0;}
这是一个函数的实现,它通过一些额外的逻辑来实现这一点,以防其他人想这样做。我真的想知道这是否已经存在

需要洛达斯

export function intersperse(arrs, delimeter) {
    let joined = [];
    for (var i = 0; i < arrs.length; i++) {
        let arr = arrs[i];
        if (!arr) continue; //handle sparse arrays
        joined.push(...arr);
        if (i === arrs.length - 1) break;
        if (_.isFunction(delimeter)) {
            joined.push(...delimeter());
        } else if (_.isArray(delimeter)) {
            joined.push(...delimeter);
        } else {
            throw new Error("unknown type");
        }
    }
    return joined;
}
导出功能穿插(arrs、delimeter){
让加入=[];
对于(变量i=0;i
这里有很多很好的答案,包括4Castle的评论。至于更改,我想为这份工作开发一个通用的
Array.prototype.intersperse()

在功能JS中,我可以为这份工作想出3个备选方案

Array.prototype.intersperse_1 = function(s){
  return this.reduce((p,c,i) => (p[2*i]=c,p), new Array(2*this.length-1).fill(s));
};
Array.prototype.intersperse_2 = function(s){
  return this.reduce((p,c,i) => (i ? p.push(s,c) : p.push(c),p),[]);
};
Array.prototype.intersperse_3 = function(s){
  return this.reduce((p,c,i) => i ? p.concat([s],[c]) : p.concat([c]),[]);
};
您应该远离第三个,因为
.concat()
是functional JS中最昂贵的操作之一。它甚至无法完成10万个项目的作业

另一方面,虽然在小尺寸阵列中总是稍快一些,但在FF和Chrome中,第一个阵列比第二个阵列快2倍甚至更多。也就是说,第一个阵列在不到1000毫秒的时间内散布一个10米的项目阵列,而对于同一个任务,第二个阵列需要2000-2500毫秒。当然,处理这种大小的阵列并不容易我根本就不喜欢第三名

因此,在这种特殊情况下,与定制解决方案相比,它可能会更加昂贵,因为我们必须将结果映射到原始值,但我想下面的代码仍然值得注意。我确信
.concat()
当数组长度超过某个数字时,采用定制解决方案将落后于此

Array.prototype.intersperse=函数{
返回此.reduce((p,c,i)=>(p[2*i]=c,p),新数组(2*this.length-1).fill(s));
}
var arr=[[1]、[2]、[3]],
结果=排列间隔([0])
.map(e=>e[0]);

console.log(JSON.stringify(result));
正如前面几次提到的,最简单的方法是

function intercalate(glue, arr){
    return arr.reduce((acc, v) => acc.concat(glue, v));
}
但这不是最好的方法,因为它会在每次迭代中创建一个新的(中间)数组,然后将其丢弃。这对于这个短的值数组并不重要,但是如果您打算在更长的数组中使用它,您可能会注意到其影响

更好的做法是创建一个数组,并在传入时将值推入其中

function intercalate(glue, arr){
    const push = (acc, v) => (Array.isArray(v)? acc.push(...v): acc.push(v), acc);
    return arr.reduce((acc, v, i) => push(i===0? acc: push(acc, glue), v), []);
}
但是,由于这个数组正在逐渐增加,它可能仍然需要分配更大的内存块并复制数据。这些任务非常有效,但仍然是不必要的(imo);我们可以做得更好

我们首先创建一个包含所有数组和中间分隔符的列表,并使用
concat.apply([],list)
将其展平。因此,我们生成一个中间数组,它的大小可以提前计算,其余的是Array.concat的问题,以及它的底层实现

function intersperse(delimiter, arr){
    if(!arr.length) return [];
    let j = 0, push = (acc, v) => (acc[j++] = v, acc);
    return arr.reduce((acc, v) => push(j===0? acc: push(delimiter, glue), v), Array(2*arr.length-1));
}
//or
function intersperse(delimiter, arr){
    if(!arr.length) return [];
    var out = Array(2*arr.length-1);
        out[0] = arr[0];
    for(var i=1, j=1; j<out.length;){
        out[j++] = delimiter;
        out[j++] = arr[i++];
    }
    return out;
}

//and

function intercalate(glue, arr){
    var emptyArray = [];
    return arr.length? 
        emptyArray.concat.apply(emptyArray, intersperse(glue, arr)): 
        emptyArray;
}
函数穿插(分隔符,arr){
如果(!arr.length)返回[];
设j=0,push=(acc,v)=>(acc[j++]=v,acc);
返回arr.reduce((acc,v)=>push(j==0?acc:push(分隔符,胶水),v),数组(2*arr.length-1));
}
//或
函数穿插(分隔符、arr){
如果(!arr.length)返回[];
var out=阵列(2*arr.length-1);
out[0]=arr[0];

对于(var i=1,j=1;jp请再添加一些示例。您需要的函数名是包含另一个元素的数组。它当前是Lodash的函数名,所以如果您希望看到它添加到库中,请向上投票!@4castle Oh cool。也许我会提交一个pull请求。谢谢!!问题可能重复。是的,非常类似。不确定是否有问题基于生成器的答案的范围。我是说该死的废话…将其输入babel.js的输出非常复杂。我不能使用join,因为它会将内容转换为字符串。哦,那么你希望结果是数组?你只需要将其展平并穿插分隔符?你能给我一个arr数组的工作示例吗要联接的数组和要散布的分隔符数组?啊,我明白了。使用Lodash的另一个示例是正确的。我添加了一个额外的带有矩阵散布的示例。您可以从缩减中删除三元语句和初始值:
ar
function intersperse(delimiter, arr){
    if(!arr.length) return [];
    let j = 0, push = (acc, v) => (acc[j++] = v, acc);
    return arr.reduce((acc, v) => push(j===0? acc: push(delimiter, glue), v), Array(2*arr.length-1));
}
//or
function intersperse(delimiter, arr){
    if(!arr.length) return [];
    var out = Array(2*arr.length-1);
        out[0] = arr[0];
    for(var i=1, j=1; j<out.length;){
        out[j++] = delimiter;
        out[j++] = arr[i++];
    }
    return out;
}

//and

function intercalate(glue, arr){
    var emptyArray = [];
    return arr.length? 
        emptyArray.concat.apply(emptyArray, intersperse(glue, arr)): 
        emptyArray;
}