到目前为止,我已经尝试过了,但是它返回了未过滤的数组:
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);
答案 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));