我的函数在将其转换为布尔值后不会删除 "false"

My function doesn't remove "false" after converting it to a boolean

我试图创建一个函数,在转换为布尔值时删除所有“false”的值,但出于某种原因,“false”项不会从数组中删除。

function bouncer(arr) {
  let y = []
  for (let i of arr) {
    if (Boolean(i) == false) {
      arr.splice(arr.indexOf(i), 1)
    }
  }
  console.log(arr)
}
bouncer([7, "ate", "", false, 9]);

迭代器(由 for..of 调用)惰性。他们不会创建一个包含所有项目的集合以在开始时进行迭代。相反,在每次迭代开始时,他们会增加索引以进行检查,并在数组中查找该索引。

在这种情况下,在索引 2 上,'' 是错误的,被 splice 删除。拼接后的数组现在是:

[7, 'ate', false, 9]

然后,迭代器继续索引 3,并检查 9false 永远不会迭代。

改用.filter

const bouncer = arr => arr.filter(Boolean);
console.log(bouncer([7, "ate", "", false, 9]));

如果您就地改变数组,向后迭代:

const bouncer = (arr) => {
  for (let i = arr.length - 1; i >= 0; i--) {
    if (!arr[i]) {
      arr.splice(i, 1);
    }
  }
  return arr;
};
console.log(bouncer([7, "ate", "", false, 9]));

您需要从数组的末尾开始循环,因为您使用 splice.

更改了元素的索引

function bouncer(arr) {
  let i = arr.length;
  while (i--) {
    if (!arr[i]) arr.splice(i, 1);
  }
  console.log(arr)
}
bouncer([7, "ate", "", false, 9]);

根据 MDN indexOf

The indexOf() method returns the first index at which a given element can be found in the array

就用Filter,很清楚

我会用 .filter() 来避免 O(n2) 算法:

let bouncer = (arr) =>
  arr.filter((e) => Boolean(e));

调用它时,必须将 return 值分配给目标数组:

someArray = bouncer(someArray);

创建一个新数组并非没有成本,但在具有许多错误值的大型输入数组上一遍又一遍地使用 .splice() 会更糟。

另请注意,您并不是真的需要 Boolean();使用 !! 隐式执行布尔类型转换:

let bouncer = (arr) =>
  arr.filter((e) => !!e);

您正在循环编辑数组,这会导致意外行为:

更新代码如下:

function bouncer(arr) {
      let y = []
      for (let i of arr) {
        if (Boolean(i) === false) {
          y.push(i)
        }
      }
      for (let i of y) {
         arr.splice(arr.indexOf(i), 1)
      }
      console.log(arr)
    }
    bouncer([7, "ate", "", false, 9]);

或更好地尝试使用以下 es6 的过滤器:

const data = [7, "ate", "", false, 9]
const filtered = arr => arr.filter(Boolean)
console.log(filtered(data))

function bouncer(arr) {
  let y = []
  for (let i of arr) {
    if (typeof i === 'boolean' && Boolean(i) == false) {
      arr.splice(arr.indexOf(i), 1)
    }
  }
  console.log(arr)
}
bouncer([7, "ate", "", false, 9]);