如何在不使用其他数组的情况下过滤数组

时间:2019-08-21 18:59:32

标签: javascript arrays filter

到目前为止,我已经尝试过了,但是它返回了未过滤的数组:

function filterRangeInPlace(array, min, max) {
  array = array.filter(item => (item >= min && item <= max));
  console.log(array);
}

let arr = [5, 3, 8, 1];

filterRangeInPlace(arr, 1, 4);

console.log(arr);

4 个答案:

答案 0 :(得分:4)

您需要返回新的过滤数组并将其分配给变量(例如arr本身):

function filterRangeInPlace(array, min, max){
  return array.filter(item => (item >= min && item <= max));
}

let arr = [5, 3, 8, 1];

arr = filterRangeInPlace(arr, 1, 4);

console.log(arr);

答案 1 :(得分:3)

返回该值并将其设置为等于自身。

function filterRangeInPlace(array, min, max) {
  return array.filter(item => (item >= min && item <= max));
}

let arr = [5, 3, 8, 1];

arr = filterRangeInPlace(arr, 1, 4);

console.log(arr);

或者您当然可以完全省略以下功能:

let arr = [5, 3, 8, 1];

arr = arr.filter(item => (item >= min && item <= max));

console.log(arr);

答案 2 :(得分:3)

您不能为此使用.filter(),因为它会返回一个新数组而不是修改原始数组。您可以自己遍历数组,删除不符合条件的元素。

您需要按索引的降序进行循环,因为删除元素会使所有其余元素的索引向下移动,并且如果您按升序进行操作,最终将跳过下一个元素。这也意味着您不能使用.forEach()之类的内置函数。

function filterRangeInPlace(array, min, max) {
  for (let i = array.length-1; i >= 0; i--) {
    if (array[i] < min || array[i] > max) {
      array.splice(i, 1);
    }
  }
}

let arr = [5, 3, 8, 1];
filterRangeInPlace(arr, 1, 4);
console.log(arr);

答案 3 :(得分:3)

如果在不创建另一个数组的情况下就地进行过滤实际上很重要,则必须进行一些传统的工作,并使用两个索引遍历该数组,并一路复制值。每次遇到未通过过滤器测试的元素时,您都会增加一个索引,而不增加另一个。最后,将数组.length重设为尾随索引:

function filterInPlace(array, fn) {
  let from = 0, to = 0;
  while (from < array.length) {
    if (fn(array[from])) {
      array[to] = array[from];
      to++;
    }
    from++;
  }
  array.length = to;
}

这具有O(n)的优势,只需在数组上传递一次,而涉及.splice()的解决方案就是O(n 2 )。

要进行“范围检查”,您可以编写另一个函数来创建给定最小值和最大值的过滤谓词:

function rangePredicate(min, max) {
  return n => n >= min && n <= max;
}

然后,您可以将其返回值传递给过滤器函数:

var arr = [1, 2, 3, ... ];
filterInPlace(arr, rangePredicate(0, 10));