我有数组a
,想在每个nt-h a
个元素之后插入元素。例如,我想将字符串“ XXX”放在数组a
的每3个元素之后,结果得到数组b
:https://jsfiddle.net/Lamik/vjfaqn3u/16/
let a= [undefined, "", 0, [], "ee", false, null, {}, Date(), true, (z)=>2*z, Array(0), NaN ];
let b= [undefined, "", 0, "XXX", [], "ee", false, "XXX", null, {}, Date(), "XXX", true, (z)=>2*z, [], "XXX", NaN];
我尝试通过这种方式做到这一点:
b=[]
a.map((x,i)=> b.push( (i+1)%3 ? x : "XXX"))
但是有一个问题-输出b
数组的长度与输入a
的长度相同,这是错误的-有什么想法或替代解决方案吗?
(更新:就地解决方案也可以;我剪切了数组a
)
答案 0 :(得分:1)
对于reduce()
或只是for
循环,这可能是更好的情况。 map()
将始终为您提供相同大小的新数组。如果您对结局和开始都非常谨慎,那么应该可以使用类似这样的方法使它在一般情况下起作用。
let arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
function insert_after(arr, str, n){
return arr.reduce((arr, item, i) =>{
arr.push(item)
if (i % n == n-1) arr.push(str)
return arr
}, [])
}
console.log(insert_after(arr, 'x', 2).join(','))
console.log(insert_after(arr, 'x', 3).join(','))
答案 1 :(得分:1)
在您的示例中,您推送但不推送到元素之后。
如果要使用map
,可以使用apply
推入一个或两个元素
a = [1,2,3,4,5,6,7,8,9,10]
b = []
a.map((x,i)=> Array.prototype.push.apply(b, (i+1)%3 ? [x] : [x, "XXX"]))
console.log(b.join(', '))
答案 2 :(得分:1)
let a= [undefined, "", 0, [], "ee", false, null, {}, Date(), true, (z)=>2*z, Array(0), NaN ];
let n = 3+1;
let currentPosition = 3;
let temp ='xxxxxx';
console.log('Before assignment:::',a.length, a);
while(currentPosition <= (a.length+1)){
a.splice(currentPosition,0,temp);
currentPosition += n;
}
console.log('new array length:::::',a.length ,a);
我希望此解决方案对您来说很好。 在插入元素之前,长度为13。在17.之后。
答案 3 :(得分:1)
根据给定的示例数组 a 和 b ,您可以尝试以下代码来获得预期的输出。
let a= [undefined, "", 0, Array(0), "eeeeeeeeee", null, "cccccccc", "bbbbbbb", "ddddddddd", Array(0), "bbbbbbb", {}, undefined, "bbbbbbb", {}, null, 0, "ddddddddd", null, "eeeeeeeeee", "ddddddddd", "bbbbbbb", undefined, "cccccccc", "ddddddddd", "ddddddddd", undefined, undefined, "eeeeeeeeee", {}, "", "", undefined, "", "eeeeeeeeee", undefined, Array(0), Array(0), 0, "ddddddddd", "", "", null, null, "bbbbbbb", "", Array(0), null, "ddddddddd", {}];
let b = [];
let j = 0, insertIndex = 15;
let insertVal = "INSERT_VAL";
for(let i=0; i< a.length;){
b[j++] = a[i++];
if(i%insertIndex ==0){
b[j++] = insertVal;
}
}
console.log(b);
答案 4 :(得分:1)
这是我的解决方案,它使用while
循环和splice方法,每个token
元素都插入N
。另外,我将逻辑包装在一个函数中。
let insertTokenEveryN = (arr, token, n) => {
// Clone the received array, so we don't mutate the
// original one. You can ignore this if you don't mind.
let a = arr.slice(0);
// Insert the <token> every <n> elements.
let idx = n;
while (idx <= a.length)
{
a.splice(idx, 0, token);
idx += n + 1;
}
return a;
};
let array = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15];
let res1 = insertTokenEveryN(array, "XXX", 2);
let res2 = insertTokenEveryN(array, "XXX", 3);
let res3 = insertTokenEveryN(array, "*", 4);
console.log(JSON.stringify(res1));
console.log(JSON.stringify(res2));
console.log(JSON.stringify(res3));
答案 5 :(得分:1)
受答案Hamlet Hakobyan和Mark Meyer的启发,我为使用地图和归约(时间复杂度 O(n))的不可变解决方案提供 oneliners / p>
let b=[]; a.forEach((x,i)=>b.push(x,...(i+1)%k?[]:["XXX"]));
let c = a.reduce((t,x,i)=>t.push(x,...(i+1)%k?[]:["XXX"])&&t,[]);
和就地解决方案(导致a
,复杂度 O(n / k))
for(let i=a.length/k|0;i;i--) a.splice(i*k,0,"XXX");
我阅读了您所有的答案并给出+1,因为它们很有趣,很难选择最佳,但最终我选择了Amaranadh Meda answer,因为他首先表明我们可以降低 O(n )到 O(n / k),其中n是数组a
的大小,k
是新插入的元素之间的间距的大小。
let a= [undefined, "", 0, [], "ee", false, null, {}, Date(), true, (z)=>2*z, Array(0), NaN ];
let k=3; // gap
// immutable -> result in b
let b=[]; a.forEach((x,i)=>b.push(x,...(i+1)%k?[]:["XXX"]));
let c = a.reduce((t,x,i)=>t.push(x,...(i+1)%k?[]:["XXX"])&&t,[]);
// in-place -> result in a
for(let i=a.length/k|0;i;i--) a.splice(i*k,0,"XXX");
console.log('b=',b);
console.log('c=',c);
console.log('a=',a);