24

I have a 2D array:

var array = [["a", "b", "c"],["a", "b", "c"],["a", "b", "c"]]

I want to delete an entire column of this array (i.e. delete every third element within each array).

There are solutions here and here, but neither of them is in javascript, so I'm having trouble relating the situations.

What's the best way to approach this problem? I don't want to use .splice() because in some cases I'll be deleting multiple columns, and the .splice() method will change the length of the array, so I end up accessing out of bounds.

Thanks!

Community
  • 1
  • 1
user3757174
  • 483
  • 2
  • 8
  • 17
  • So you'll endup with `[["a", "b"],["a", "b"],["a", "b"]]`? – Rahil Wazir Jul 17 '14 at 19:56
  • 1
    Do you want to delete the e.g. third item in each... (truncating the length of the inner arrays)? or do you want to set it to null or an empty string? - It isn't clear. – scunliffe Jul 17 '14 at 19:57
  • there's no automatic function for this. "multi-dimensional" arrays in JS are just arrays-of-arrays. You'll have to iterate over the parent array and delete the appropriate element from each child array. "columns" are a human convenience which don't directly translate into how they actually work in the actual JS engine. – Marc B Jul 17 '14 at 19:58
  • I want to truncate the length. (e.g. deleting every third element would give me: [["a", "b"],["a", "b"],["a", "b"]] – user3757174 Jul 17 '14 at 19:58
  • Have you tried with delete? – keypaul Jul 17 '14 at 20:03

7 Answers7

33

Try using slice. It won't alter any changes to your original array

var array = [["a", "b", "c"],["a", "b", "c"],["a", "b", "c"]]

var x = array.map(function(val) {
  return val.slice(0, -1);
});

console.log(x); // [[a,b],[a,b],[a,b]]
adiga
  • 34,372
  • 9
  • 61
  • 83
Rahil Wazir
  • 10,007
  • 11
  • 42
  • 64
10

This function doesn't use splice and it removes any column you want:

function removeEl(array, remIdx) {
 return array.map(function(arr) {
         return arr.filter(function(el,idx){return idx !== remIdx});  
        });
};

Hope this is what you are looking for

sergeyz
  • 1,339
  • 10
  • 14
9

Iterate through the array and splice each sub array:

var idx = 2;
for(var i = 0 ; i < array.length ; i++)
{
   array[i].splice(idx,1);
}

JSFiddle.

Edit: I see you don't want to use splice due to out-of-bounds problems and array length changing. So:

1.You can check if you're out of bounds and skip the slice.
2.You can create an array of indexes you want to delete and simply create new arrays from the indexes that don't appear in that array (instead of deleting, create new arrays with the opposite condition).

Something like this:

var array = [
    ["a", "b", "c"],
    ["a", "b", "c"],
    ["a", "b", "c"]
];

var idxToDelete = [0,2];

for (var i = 0; i < array.length; i++) {
    var temp = array[i];
    array[i] = [];
    for(var j = 0 ; j < temp.length ; j++){
        if(idxToDelete.indexOf(j) == -1) // dont delete
        {
            array[i].push(temp[j]);
        }
    }
}

New JSFiddle.

Community
  • 1
  • 1
Amir Popovich
  • 29,350
  • 9
  • 53
  • 99
  • 2
    Regarding his "out of bounds" issue, you could just remove the indexes in descending order... That is, start at the *highest* index to remove and just work your way down. – Casey Falk Jul 17 '14 at 20:13
5

You can use filter to remove columns without the need to modify the original array.

var array = [["a", "b", "c"],["a", "b", "c"],["a", "b", "c"]]
var removeIndex = 1

const filtered = array.map(v => v.filter((_, i) => i !== 1))
// output: [["a", "c"], ["a", "c"], ["a", "c"]]

You can also remove multiple columns with the same approach.

var array = [["a", "b", "c"],["a", "b", "c"],["a", "b", "c"]]
var removeIndexes = [0, 2]

const filtered = array.map(v => v.filter((_, i) => !removeIndexes.includes(i)))
// output: [["b"], ["b"], ["b"]]
juniorerico
  • 51
  • 1
  • 4
3

use the map function and splice function for your solution. like this

var array = [["a", "b", "c"],["a", "b", "c"],["a", "b", "c"]];

array = array.map(function(item){
        // the 0,2 tells the splice function to remove (skip) the last item in this array
        return item.splice(0,2);
});

console.log(array);
// [["a", "b"],["a", "b"],["a", "b",]];

don't use delete to delete items from a javascript array. the reason is that delete will toss the item but don't update the internal length variable.

example

var array = ["a", "b", "c"];

delete array[3];
console.log(array);
// ["a", "b"]
console.log(array.length);
// 3

array = array.splice(0,2);
console.log(array);
// ["a", "b"]
console.log(array.length);
// 2

use splice this sets the correct length and delete the item of the array.

ins0
  • 3,918
  • 1
  • 20
  • 28
2

splice is cool. It resizes the array as it removes things so you don't end up with nulls. So using splice you just have to iterate through each row and remove the right element.

var removeCol = function(arr2d, colIndex) {
    for (var i = 0; i < arr2d.length; i++) {
        var row = arr2d[i];
        row.splice(colIndex, 1);
    }
}

http://jsfiddle.net/eB8LD/

Alex Wayne
  • 178,991
  • 47
  • 309
  • 337
-1

Useful code snipped that creates an independent copy of an array

use slice method inside map. Here is an example:

let arrayA = ['a', 'b', 'c', 'd']

let arrayB = arrayA.map((val) => {
      return val.slice()
})

arrayB[2] = 'Z';

console.log('--------- Array A ---------')
console.log(arrayA)

console.log('--------- Array B ---------')
console.log(arrayB)

Note: In Angular 10, I used different methods to get an independent copy of an array but all failed. Here are some of them:

arrayB.push(arrayA) // failed    
arrayB = Object.create(arrayA) // failed    
arrayB = arrayA.splice() // failed

All failed methods were copying references along with data.

WasiF
  • 26,101
  • 16
  • 120
  • 128