Как отфильтровать () NaN, null, 0, false в массиве (JS)

меня попросили отфильтровать NaN, null, 0, false на массив.

к счастью, я ответил на вопрос.

function bouncer(arr) {
  function filterer(arr) {
     return arr > 0|| isNaN(arr) === true;
  }
  arr = arr.filter(filterer);
  return arr;
}

//example input
bouncer([0, 1, 2, 3, 'ate', '', false]); //output [1, 2, 3, 'ate']

но дело в том, что я действительно не знаю, как я придумал ответ или, скорее, я не знаю, как это работает. Особенно на arr > 0 как фильтр узнал, что arr читается на arr[1], arr[2] и т. д.. без использования цикла для перебора в массиве.

или может просто объяснить, как код работает. - "Я пытался объяснить это ясно..."--6-->

10 ответов


посмотреть docs на Array.filter. Обратите внимание, в частности, на аргументы обратного вызова:

функция для проверки каждого элемента массива. Вызывается с аргументами (элемент, индекс, массив). Возвращает true, чтобы сохранить элемент, false в противном случае.

Так что в вашем случае arr - это элемент (и плохо названный, отсюда ваша путаница). Фильтруйте петли через Ваш массив и для каждого элемента он вызывает вас обратный вызов, передавая элемент в текущем должность arr.

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

и, конечно, внутренне, это цикл через Ваш массив. Вы не можете фильтровать свой (несортированный) массив, не касаясь каждого элемента в массиве. Посмотрите на polyfil в ссылке на получить представление о том, как это может работа (может быть, потому что это деталь реализации, которая может отличаться с разными движками javascript, но, несомненно, будет включать цикл где-то), он петляет по вашему массиву, вызывает обратный вызов (обратите внимание на аргументы), и если обратный вызов возвращает true, он попадает в массив результатов.


если вас попросят отфильтровать NaN, null, 0, false в массиве, тогда ваши решения действительно не работают.

ввода:

bouncer([0, 1, 2, 3, 'ate', '', false, NaN]);

получит выход:

[1, 2, 3, 'ate', NaN]

чтобы отфильтровать все "ложные" значения, вы можете просто использовать Boolean:

function bouncer(arr) {
  return arr.filter(Boolean);
}

bouncer([0, 1, 2, 3, 'ate', '', false, NaN]);

выход:

[1, 2, 3, 'ate']

С Boolean конструктор также является функцией, он возвращает либо true для "правдивого" аргумента или false для "ложного" аргумента. Если значение опущено или равно 0, -0, null, false, NaN, undefined, или пустая строка ("") объект имеет значение false. Все остальные значения, включая любой объект или строку "false" создайте объект с начальной стоимостью true.


вы также можете использовать функцию идентификации вместо Boolean.

function bouncer(arr) {
  return arr.filter(x => x);
}

Я также работаю над алгоритмом Free Code Camp Falsy Bouncer. Я нашел самый простой способ сделать это:

function bouncer(arr) {
   return arr.filter(Boolean);
}

The filter () метод создает новый массив со всеми элементами, которые проходят тест, реализованный предоставленной функцией.

С false, null, 0, "", undefined и NaN все ложь значения в JavaScript, поэтому они вернут false при испытании.

function bouncer(arr) {
  var array = arr.filter(function(val){
    return val;
  });
  return array;
}

только значения, которые не вернет false будет добавлено к массив.


не было бы более элегантным, чтобы основываться на предположении, что все нежелательные элементы отбрасываются на false, когда ожидается логическое значение, поэтому:

function clear (arr){
   var stripped = [];
   for (i = 0, len = arr.length; i < len; i++){
      if (arr[i])
         stripped.push(arr[i]);
   }
   return stripped;
}

функция для проверки каждого элемента массива. Вызывается с аргументами (элемент, индекс, массив). Возвращает true, чтобы сохранить элемент, false в противном случае

если вы просто хотите, объяснение. Массив filter() как имя предложить. Удалите ненужный элемент, если условие падает неправильно (false).

(arr > 0|| isNaN(arr) === true)

0,  false || false  //removed
1,  true || false  
2,  true || false
3,  true || false
'ate', false || true
'',   false|| false  // removed
false  false || false //removed

выход:

[1, 2, 3, "ate"]

поскольку я начинающий кодирование o, моя логика пошла использовать примитивные логические значения для сравнения элементов отфильтровано, но это было до того, как я прочитал ссылку на объект Boolean, вы видите, что как там написано, "Значение, переданное в качестве первого параметра, при необходимости преобразуется в логическое значение. Если значение опущено или равно 0, -0, null, false, NaN, undefined или пустой строке ( "" ), объект имеет начальное значение false. Все остальные значения, включая любой объект или строку " false", создать объект с начальным значением true." Так что логика, поскольку фильтр возвращает значение, если его значение true или false, вы должны возвращать значения, если они являются истинными. Кроме того, я не узнал все о методе фильтра, для чего я исследовал, у меня есть немного больше информации, которую я попытаюсь объяснить здесь.

переопределение метода (он уже существует, просто для понимания) метод filter принимает функцию предикат, то есть функция, которая получает ля value и возвращает true или false.

результаты var-это пустой массив, в котором результаты будут выталкиваться методом push. Мы используем метод forEach с этим, (это, в этом контексте применяется к прототипу массива, это означает, что у вас будет метод фильтра, доступный для каждого массива, который вы определяете, с синтакс массива.метод (args) в этом случае массив.фильтр(аргументы)) определенные ресурсы https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/prototype

Теперь мы запустим операцию в каждом элементе массива с помощью метода forEach, теперь мы применим функцию предиката к элементу itch массива, и если он вернет true, добавим его к результатам.

Array.prototype.filter = function(predicate){   
    var results = [];

    this.forEach(function(item) {   
        if (predicate(item)) {
            results.push(item);
        }

    });
};

//-------------------------------Правильное Решение---------------------------

function bouncer (arrToFilter){

    return arrToFilter.filter(Boolean);
}

//----------код без способ фильтрования---------

function bouncerNoFilterMethod(arrToFilter){
    var results = [];

    arrToFilter.forEach(function(arrToFilter){
        if(arrToFilter){
            results.push(arrToFilter);
        }
    });

    return  results;    
}

console.log(bouncerNoFilterMethod([7, "ate", "", false, 9]));
console.log(bouncerNoFilterMethod(["a", "b", "c"]));
console.log(bouncerNoFilterMethod([false, null, 0, NaN, undefined, ""]));
console.log(bouncerNoFilterMethod([1, null, NaN, 2, undefined]));
console.log(bouncer([7, "ate", "", false, 9]));
console.log(bouncer(["a", "b", "c"]));
console.log(bouncer([false, null, 0, NaN, undefined, ""]));
console.log(bouncer([1, null, NaN, 2, undefined]));

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


похоже, что Boolean-это самое простое исправление / ответ для задачи "FreeCodeCamp", однако может быть полезно попробовать пару вещей, чтобы получить представление о" почему "и"как".

function bouncer(arr) {
      return arr.filter(function(val){
        return val;
     });
    }

это оценивает все, проходящее через фильтр, используя переданную функцию (обратный вызов), которая возвращает значения. Если он не возвращает значение, которое null и т. д. не будет, он не будет включен в возврат. По крайней мере, этот метод помог мне понять, почему, а не просто пройти тест.


function bouncer(arr) {
  // Don't show a false ID to this bouncer.

  function isFalsyBouncer(value){
    if(Boolean(false)||Boolean(null)||Boolean(0)||Boolean("")||Boolean(undefined)||Boolean(NaN)){

    }else{
      return value;
    }
  }
  var filtered=arr.filter(isFalsyBouncer);
  return filtered;
}