0

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 splices' 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.

2
  • arr is an array of arrays. Therefore, arr.indexOf(1) and arr.indexOf(6) will be -1. Commented Jan 22, 2015 at 23:20
  • You're right Oriol :) That was a mistake I made while I was simplifying the question looking at my real code :) I fixed it. Commented Jan 23, 2015 at 0:15

3 Answers 3

2

Can you just add the second one first? That won't change the index of the first.

Sign up to request clarification or add additional context in comments.

1 Comment

I've changed my mind :) The main idea is the same and you were the first who answered,
1

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

DEMO

1 Comment

Thanks for the answer and code. But helloChris was the first who gave the trick :)
1

I changed a few things, but its working. Oriol is correct the indexOfs 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

1 Comment

Thanks for answer! +1 for effort :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.