Reputation: 7950
I have an array of arrays.
var arr = [[1,2,3,4,5],[2,3,4,5,6],[3,4,5,6,7],[4,5,6,7,8],[5,6,7,8,9], [6,7,8,9,10], [7,8,9,10,11]];
I want to add a new item in front of and back of multiple items at specific indexes.
What I want to achieve is:
var new_arr = [["x",1,"x",2,3,4,5], [2,3,4,5,"x",6,"x"], [3,4,5,"x",6,"x",7], [4,5,"x",6,"x",7,8], [5,"x",6,"x",7,8,9], ["x",6,"x",7,8,9,10], [7,8,9,10,11]];
The issue is, when I use splice
to insert a new item inside the iterated arrays, indexes does change. Because splice
is a destructive function.
Here is what I tried:
var result = [];
_.each(arr, function(item, index) {
index_a = item.indexOf(1);
index_b = item.indexOf(6);
var temp_item = item.slice(0);
if(~index_a || ~index_b) {
temp_item.splice(index, 0, "x");
temp_item.splice(index + 2, 0, "x");
if(index_b > -1) {
temp_item.splice(index, 0, "x");
}
}
result.push(item);
}
During the iteration above, the first splice
works just fine. But the second "x"
is not placed properly. I think the reason is first splice
s' effect on the temp_item
array. Because number of items in the array is changing.
So how can I achieve what I want? Thank you.
Upvotes: 0
Views: 2385
Reputation: 2214
I changed a few things, but its working. Oriol is correct the indexOf
s you had would always be -1
.
In my solution I map over the matrix and evaluate if each row contains 1
or 6
, if it does cache the element by index and splice the index with "x",
elm"x"
var matrix = [
[1,2,3,4,5],
[2,3,4,5,6],
[3,4,5,6,7],
[4,5,6,7,8],
[5,6,7,8,9],
[6,7,8,9,10],
[7,8,9,10,11]
];
function wrapElementWithX(arr, index) {
// cache the element
var elm = arr[index];
// splice with the "x", element, "x"
arr.splice(index, 1, 'x', elm, 'x');
}
matrix.map(function (row) {
var indexOf1 = row.indexOf(1);
var indexOf6 = row.indexOf(6);
// if the row has `1`
// wrap
if (~indexOf1) {
wrapElementWithX(row, indexOf1);
}
// if the row has `6`
// wrap
if (~indexOf6) {
wrapElementWithX(row, indexOf6);
}
return row;
});
also go a jsfiddle example
Upvotes: 1
Reputation: 171669
I think this does what you want. Splicing the higher index first maintains lower index posiitoning
function padArr(val, arr){
arr.forEach(function(subArr){
var idx = subArr.indexOf(val);
if( idx >-1){
subArr.splice(idx+1,0,'x' );
subArr.splice(idx,0,'x')
}
});
return arr;
}
// usage
arr = padArr(1, arr);
arr = padArr(6, arr);
Upvotes: 1
Reputation: 1894
Can you just add the second one first? That won't change the index of the first.
Upvotes: 2