Я хочу удалить индекс в массиве внутри массивов большего размера; например:

 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' }]
]

Я хочу удалить все объекты с general == false, чтобы получить следующее:

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

Я сделал это, но это не работает:

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

Заранее спасибо.

2
mohammad 17 Ноя 2020 в 15:20

2 ответа

Лучший ответ

Проблема в том, что у вас есть два объекта с general: false рядом друг с другом. Вы смотрите на индекс j и, возможно, удаляете эту запись, а затем переходите к следующей записи после нее - но когда вы удаляете запись, та после нее перемещается в индекс j и никогда не проверяется.

Три варианта:

  1. Когда вы удаляете запись, уменьшите j, чтобы проверить запись, которая переместилась на следующем проходе.

  2. Петля назад от конца.

  3. Используйте filter для создания новых массивов вместо того, чтобы изменять массивы на месте, возможно, в сочетании с map во внешнем массиве:

№2 более популярен, чем №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)
        }
    }
}

Живой пример:

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

Вот # 3:

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

Живой пример:

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);
2
T.J. Crowder 17 Ноя 2020 в 12:24

Оказывается, редукт - твердый раствор.

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)

Сначала я подумал об этом, но это не соответствует выводу OP.

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)
2
mplungjan 17 Ноя 2020 в 12:44