Зацикливание на вложенных массивах

#javascript

#javascript

Вопрос:

Я выполняю упражнение, в котором меня просят удалить массивы, элементы которых соответствуют другой переменной.

например

filteredArray([[10, 8, 3], [14, 6, 23], [3, 18, 6]], 18)

должен возвращать [[10, 8, 3], [14, 6, 23]]

Учитывая тот факт, что мы работаем с вложенными массивами, я подумал об использовании двойного for для выполнения цикла в каждом элементе.

Вот так:

 function filteredArray(arr, elem) {
  let newArr = [];
  for (let i = 0; i < arr.length; i  ) {
    for (let j = 0; j < arr[i].length; j  ) {
      if (arr[i][j] != elem) {
        newArr.push(arr[i]);
      }
    }
    // change code above this line
    return newArr;
  }
}

console.log(filteredArray([[3, 2, 3], [1, 6, 3], [3, 13, 26], [19, 3, 9]], 3));  

Ожидаемый результат должен был иметь пустой массив, но это дает мне:
[3, 2, 3]

Правильное решение заключается в следующем:

 function filteredArray(arr, elem) {
  let newArr = [];
  for (let i = 0; i < arr.length; i  ) {
    if (arr[i].indexOf(elem) == -1) { //Checks every parameter for the element and if is NOT there continues the code
      newArr.push(arr[i]); //Inserts the element of the array in the new filtered array
    };
  };
  return newArr;
};

console.log(filteredArray([[3, 2, 3], [1, 6, 3], [3, 13, 26], [19, 3, 9]], 3));  

Что имеет смысл, но я не понимаю, почему мой неправильный.

Комментарии:

1. Ваше arr[i][j] != elem , ну 2 != 3, так что это пройдет.. Кроме того, у вас тоже есть свой { amp; } , поэтому он всегда будет возвращаться в первом цикле.

Ответ №1:

Ваша проблема в:

 if (arr[i][j] != elem) {
  newArr.push(arr[i]);
}
  

Вы помещаете свой массив в newArr каждый раз, когда внутренний элемент ( newArr[i][j] ) не равен элементу фильтра ( elem ). Вместо этого вы хотите вставить его в, newArr если все элементы в arr[i] не равны elem . Вы могли бы сделать это несколькими способами, одним из способов было бы использовать переменную, found которая действует как флаг, указывающий, была ли elem найдена в каком-либо из внутренних списков, а затем добавить ее, если она не была найдена:

 function filteredArray(arr, elem) {
  let newArr = [];
  for (let i = 0; i < arr.length; i  ) {
    let found = false;
    for (let j = 0; j < arr[i].length; j  ) {
      if (arr[i][j] == elem) {
        found = true;
      }
    }
    
    if(!found) {
      newArr.push(arr[i]);
    }
  }
  
  // move return out of for loop
  return newArr;  // change code above this line
  
}
console.log(filteredArray([[3, 2, 3], [1, 6, 3], [3, 13, 26],
[19, 3, 9]], 3));  

Ответ №2:

Вы получаете, [3, 2, 3] потому что вы возвращаетесь из внутри первого for цикла. Таким образом, он проверяет только первый внутренний массив. Даже если вы переместите его наружу, будет возвращен весь 2d-массив, потому что в каждом внутреннем массиве есть элемент, который не выполнит arr[i][j] == elem условие.

В качестве альтернативы вы могли бы использовать filter и includes вот так:

 function filteredArray(arr, elem) {
  return arr.filter(a => !a.includes(elem))
}
console.log(filteredArray([[3, 2, 3], [1, 6, 3], [3, 13, 26], [19, 3, 9]], 3));  

Ответ №3:

Вы проверяете каждый элемент подмассива, и если это не соответствует elem , вы помещаете подмассив в результат. Это означает, что для [3, 18, 6] в вашем первом примере он проверит 3 на elem ( 18 ), затем отправит этот массив, проверит 18 на elem , что не приведет к полному выполнению условия, затем он проверит 6 на 18 , который снова соответствует, массив будет отправлен снова. Вместо этого вы должны сверить весь массив со значением, затем нажать.

  outer: for (let i = 0; i < arr.length; i  ) {
  for (let j = 0; j < arr[i].length; j  ) {
    if (arr[i][j] == elem) {
      continue outer; // if one matches, exit the inner loop
    }
    // all checked, push
    newArr.push(arr[i]);       
  }
 }
  

Ответ №4:

В вашем коде есть некоторые неправильные вещи:

  • Вы разрешаете возврат в цикле for.
  • Вы проверяете каждый элемент в каждом подмассиве и нажимаете на результирующий массив при наличии разницы

Я редактирую ваш код, как показано ниже:

     function filteredArray(arr, elem) {   
let newArr = [];   
for (let i = 0; i < arr.length; i  ) {  var check = false;
    for (let j = 0; j < arr[i].length; j  ) {
      if (arr[i][j] == elem) {
       check = true;
      }
    }
       } // change code above this line
    return newArr; 
}