【问题标题】:Javascript array.filter() element being skippedJavascript array.filter() 元素被跳过
【发布时间】:2018-01-21 22:21:03
【问题描述】:

我正在尝试删除给定参数中的公共元素,并且 创建具有唯一元素的最终数组。 在下面的示例中,我的最终数组给了我 [1,3,4,5] 而不是 [1,4,5]。 我进行了调试,元素 (3) 之一没有通过循环。 在元素 (2) 之后,它跳到元素 (4)。我很困惑为什么会这样?我的代码有什么问题吗?任何帮助表示赞赏。 谢谢

  function arrayBreaker(arr) {
  let test = [];
  test.push(arguments[1]);
  test.push(arguments[2]);
  let target = arguments[0];

  target.filter(val => {
  if (test.indexOf(val) > -1) {
  target.splice(target.indexOf(val), 1);
  }
 });
  return target;
 }

console.log(arrayBreaker([1,2,3,4,5], 2, 3));

【问题讨论】:

  • filter 中,您需要返回一个真值或假值,而不是改变数组。
  • 正如 Xufox 所说,您不能使用 filter 进行变异,您想使用 .forEach 进行此类操作。
  • @imixtron:他是这么说的吗?
  • @imixtron 谢谢你的信息。我仍然无法使用 forEach 获得正确的输出。我刚刚用 forEach 替换了过滤器。我做错了吗?
  • @Aditya:.forEach() 不会有什么不同。第一条评论的意思是你在.filter回调中返回条件的结果,并分配(或返回)结果数组。但是你真的需要改变原始数组吗?

标签: javascript arrays arguments


【解决方案1】:

您像通用迭代器一样使用.filter(),并改变了您正在迭代的数组,这会导致问题,因为迭代器不知道您正在删除的项目。

如果你需要改变原始数组,而不是从.filter()回调返回.indexOf()操作的结果,或者更好的是,使用.includes()代替,然后在第一次清除后将结果复制到原始它。

function arrayBreaker(target, ...test) {
  const res = target.filter(val => !test.includes(val));
  target.length = 0;
  target.push(...res);
  return target;
}

console.log(arrayBreaker([1, 2, 3, 4, 5], 2, 3));

如果你不需要变异,但可以返回一个副本,那就更简单了。

function arrayBreaker(target, ...test) {
  return target.filter(val => !test.includes(val));
}

console.log(arrayBreaker([1, 2, 3, 4, 5], 2, 3));

【讨论】:

  • 非常感谢!!上面的代码又短又漂亮,这就是我要找的!再次感谢您!
【解决方案2】:

Array 正在根据过滤条件返回一个新数组,在这种情况下,您正在检查测试索引。如果要保留该值,则在回调函数中期望为 true,否则返回 false。在您的情况下,您不应该在过滤器回调中分割目标,而是:

function arrayBreaker(arr) {
  let test = [];
  test.push(arguments[1]);
  test.push(arguments[2]);
  let target = arguments[0];

  let newArray = target.filter(val => {
    if (test.indexOf(val) > -1) {
      // filter value out
      return false;
    }
    // keep the val inside new array
    return true;
  });
  return newArray;
}
console.log(arrayBreaker([1,2,3,4,5], 2, 3));

有关数组过滤器的更多信息,请查看此处的文档: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter

根据您的用例,我认为有几件事情会有所帮助,首先我会声明函数参数,因此很明显 arrayBreaker 需要多个参数。其次,我希望第二个参数作为一个数组,因为我们需要多个值。如下所示:

function arrayBreaker(arr, filterValues) {
  return arr.filter(val => {
    if (filterValues.indexOf(val) > -1) return false;
    return true;
  })
}
console.log(arrayBreaker([1,2,3,4,5], [2, 3]));

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-07-17
    • 2011-07-02
    • 1970-01-01
    • 2014-07-09
    • 1970-01-01
    • 2015-07-22
    • 1970-01-01
    相关资源
    最近更新 更多