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;
}