2

I want to remove an index in an array inside a bigger arrays; for example:

 let myArray = [
  [{general : true, name: 'a' },{general : true, name: 'b' },{general : false, name: 'c' }],
  [{general : false, name: 'd' },{general : true, name: 'e' },{general : false, name: 'f'}],
  [{general : true, name: 'i' },{general : false, name: 'h' },{general : false, name: 'g' }]
]

I want to remove all objects with general == false to get this:

myFilteredArray = [
      [{general : true, name: 'a' },{general : true, name: 'b' }],
      [{general : true, name: 'e' }],
      [{general : true, name: 'i' }]
    ]

I did this but it doesn't work:

let l = myArray.length;
      for (let i = 0; i < l; i++) {
        for (let j = 0; j < myArray[i].length; j++) {
          if(!myArray[i][j].general){
            myArray[i].splice(j,1)
          }
        }
      }

thanks in advance.

0

2 Answers 2

2

The problem is when you have two objects with general: false next to each other. You're looking at index j, and possibly removing that entry, and then moving on to the next entry after it — but when you remove an entry, the one after it moves up to index j and never gets checked.

Three options:

  1. When you remove the entry, decrement j so you check the entry that moved on the next pass.

  2. Loop backward from the end.

  3. Use filter to create new arrays, rather than modifying arrays in place, perhaps combined with map on the outer array:

#2 is more popular than #1:

let l = myArray.length;
for (let i = 0; i < l; i++) {
    for (let j = myArray[i].length - 1; j >= 0; --j) {
        if (!myArray[i][j].general) {
            myArray[i].splice(j,1)
        }
    }
}

Live example:

let myArray = [
    [{general : true, name: 'a' },{general : true, name: 'b' },{general : false, name: 'c' }],
    [{general : false, name: 'd' },{general : true, name: 'e' },{general : false, name: 'f'}],
    [{general : true, name: 'i' },{general : false, name: 'h' },{general : false, name: 'g' }]
];

let l = myArray.length;
for (let i = 0; i < l; i++) {
    for (let j = myArray[i].length - 1; j >= 0; --j) {
        if (!myArray[i][j].general) {
            myArray[i].splice(j,1)
        }
    }
}
console.log(myArray);

Here's #3:

myArray = myArray.map(subarray => subarray.filter(({general}) => general));

Live example:

let myArray = [
    [{general : true, name: 'a' },{general : true, name: 'b' },{general : false, name: 'c' }],
    [{general : false, name: 'd' },{general : true, name: 'e' },{general : false, name: 'f'}],
    [{general : true, name: 'i' },{general : false, name: 'h' },{general : false, name: 'g' }]
];

myArray = myArray.map(subarray => subarray.filter(({general}) => general));
console.log(myArray);

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

2 Comments

Your 3rd is the best
@mplungjan - That's very situationally-dependent. It's the one I'd use if I didn't have a good reason not to, though.
2

It turns out reduce is a solid solution

let myArray = [
  [{general : true, name: 'a' },{general : true, name: 'b' },{general : false, name: 'c' }],
  [{general : false, name: 'd' },{general : true, name: 'e' },{general : false, name: 'f'}],
  [{general : false, name: 'x' },{general : false, name: 'y' },{general : false, name: 'z' }], // all false
  [{general : true, name: 'i' },{general : false, name: 'h' },{general : false, name: 'g' }]
]

const filtered = myArray.reduce((acc, arr) => {
  let flt = arr.filter(item => item.general)
  if (flt.length) acc.push(flt) 
  return acc; 
},[]);

console.log(filtered)

I first thought this, but it is not matching OP's output.

let myArray = [
  [{general : true, name: 'a' },{general : true, name: 'b' },{general : false, name: 'c' }],
  [{general : false, name: 'd' },{general : true, name: 'e' },{general : false, name: 'f'}],
  [{general : true, name: 'i' },{general : false, name: 'h' },{general : false, name: 'g' }]
]

const filtered = myArray.map(arr => arr.filter(item => item.general)).flat()

console.log(filtered)

6 Comments

@kopischke Not sure I understand
But if I do that, then it does not look like OP wants - then it looks like my second example
Ah, sorry, totally misread that, my bad. Forget my remarks.
The second code example has thrown me. Your first one works as intended, correct? Upvoted.
reduce when you're not doing functional programming with predefined, reusable reducers is overcomplicated at the best of times, but particularly so when the value being carried around (the new array) never changes. Just use a loop. (Or, of course, the map/filter we both like. :-) )
|

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.