我使用过滤器对吗?我不知道为什么这个解决方案有效

时间:2018-12-08 20:25:16

标签: javascript filter

我现在正在研究FCC基本算法,当我通过练习时,我还没有完全理解它为什么起作用,因为当我将事情更改为我认为应该的样子时,这是行不通的,但是当我改变事物以至于我觉得它们错了时,它仍然有效。

例如,我将true更改为false,它仍然有效,或者我只输入true,它仍然有效,或者我只说了return value,它仍然有效。过滤器是否会自动删除 fassy 值?

这是我的代码。我无法使用的原始代码显示为if (value === true)

function bouncer(arr) {
  let x = arr.filter(value => {
    if (value !== true)
      return value;
  })
  console.log(x);
  return x;
}   

bouncer([7, "ate", "", false, 9]);

从数组中删除所有 falsy 值。

JavaScript中的

Falsy 值为false,null,0,“”,未定义和NaN。

更新

感谢所有答案,它们对于消除我的困惑都非常有帮助。

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

bouncer([7, "ate", "", false, 9]);

这是我最终重写的解决方案,现在了解了我为什么做我做的事。

3 个答案:

答案 0 :(得分:2)

您的回调,

if (value !== true)
  return value;

等同于

return value;

在您的情况下,因为数组中的所有元素都不是true,所以value !== true始终成立。

如果将其更改为

if (value !== false)
    return value;

它对于大多数数组元素仍然执行return value;。唯一的例外是false,为此您的函数将返回undefined(因为未执行任何显式的return语句)。 undefined是虚假的,因此return false将其与filter相同(因为filter只关心回调返回的是真还是假)。因此,如果元素为falsereturn value相同,最后不返回值。

另一方面,如果将其更改为

if (value === true)
    return value;

然后,如果当前元素为true,则您的回调将返回true,并为其他任何值返回undefined。最终结果是删除所有非true的元素(在您的情况下是所有元素,因为您的输入数组不包含true)。

如果要删除伪造的值,您可以简单地说

arr.filter(value => { return value; })
// or:
arr.filter(value => value)

因为您使用值本身作为条件:filter删除了任何看起来虚假的内容;一切看起来正确的东西都会保留下来。

如果您感到困惑,也许看看这个自定义(简化)的filter实现可以解决问题:

function my_filter(arr, fn) {
    var results = [];
    for (var i = 0; i < arr.length; i++) {
        if (fn(arr[i])) {
            results.push(arr[i]);
        }
    }
    return results;
}

// Usage would be something like:

console.log(my_filter([7, "ate", "", false, 9], value => value));

答案 1 :(得分:1)

filter遍历数组。在每个元素迭代中,都会调用回调。

如果您在回调函数中返回一个“真”值,则该元素将保留在结果数组中,否则就不会。

您的困惑源于您认为您需要以某种方式返回value参数的事实。 您不

看这个例子:

var animals = ['dog', 'dog', 'cat', 'cat']

var cats = animals.filter(value => {
  if (value === 'cat') {
    return true
  } else {
    return false
  }
})

console.log(cats)

当然,以上内容可以简化为:

var animals = ['dog', 'dog', 'cat', 'cat']

var cats = animals.filter(value => {
  return value === 'cat'
})

console.log(cats)

就是这样。

答案 2 :(得分:1)

如果您的目的是返回仅保留真实值的数组,请执行以下操作:

.filter(Boolean)

在您对filter的回调中,您并不总是返回一个值,否则,将不会保留相应的值。此外,对于!=====之类的运算符,您正在进行 strict 比较。因此,value === true将只匹配true,而不会匹配其他真实值。同样,value !== true仍将匹配某些真实值(不是true)。