到目前为止,我尝试了这个方法,但它返回未经过滤的数组:
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);
到目前为止,我尝试了这个方法,但它返回未经过滤的数组:
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);
如果实际上很重要在不创建另一个数组的情况下进行过滤,你必须有点老派,在数组中使用两个索引进行迭代,并沿途复制值。每次遇到未通过过滤测试的元素时,您将增加一个索引,但不会增加另一个索引。在完成后,将数组 .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(n2)。
要进行“范围检查”,您可以编写另一个函数,根据最小值和最大值创建一个过滤谓词:
function rangePredicate(min, max) {
return n => n >= min && n <= max;
}
接着,您可以将该返回值传递给过滤器函数:
var arr = [1, 2, 3, ... ];
filterInPlace(arr, rangePredicate(0, 10));
fn
版本以完善答案?谢谢。 - Robert Hovhannisyanfn
可以是任何函数,就像你将传递给 .filter()
的函数一样。如果它返回 true
,则该值包含在最终数组中,否则不包含。 - Pointyarr
本身):
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);
.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);
array.splice()
,那么您需要这样做。我猜您可以继续前进并递减 i
。 - BarmarforEach
,它没有提供备份的方式。 - Barmar返回该值并将其设置为自身。
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);
.filter()
总是会创建一个新的数组。你的代码不起作用,因为函数中对array
的赋值是对参数的赋值,而JavaScript是一种按值传递的语言。 - Pointy.filter()
不像for
循环那样,它实际上是在数组实体上应用过滤器并返回一个新的过滤后的数组。它不像for
循环那样对实际数组进行更改。因此,当您需要过滤任何数组时,必须使用一个变量来保存过滤后的数组结果,或者只需使用for
循环并从数组中删除不满足条件的条目,这会影响原始数组元素。 - Neel Rathod