构建自己的过滤器回调函数

时间:2018-03-19 01:01:39

标签: javascript arrays

如果我调用过滤器函数,我会返回此数组[1,,3,...]。从哪里来的额外逗号?我不明白这种效果。有人可以向我解释一下吗? 数组应该是:[1,3,5]。

class List {
    constructor(values = []) {
        this._list = values;
    }

    
	filter(func) {
		let newList = new Array();
		let indexList = 0;
		let indexNewList = 0;

		while (this._list[indexList] != undefined) {
			if (func(this._list[indexList]) === true) {
				newList[indexNewList] = this._list[indexList];
				indexNewList++;
			}
			indexList++;
		}
		this._list = newList;
		return this;
	}
  
  get values() { return this._list }
}

var isOdd = function (x) {
    return x % 2 === 1;
};

var list = new List([1, 2, 3, 4, 5]);
console.log(list.filter(isOdd).values);

3 个答案:

答案 0 :(得分:0)

如果列表中的项目与过滤器匹配,则您将其插入原始列表中项目索引的新列表中。您只想将该项目附加到新列表中。

使用另一个变量来跟踪元素应插入到新列表中的索引:

let newList = new Array();
let indexList = 0;
let newIndex = 0;

while (this._list[indexList] != undefined) {
    if (func(this._list[indexList]) === true) {
        newList[newIndex] = this._list[indexList];
        newIndex++;
    }
    indexList++;
}

newIndex变量只会在项目插入newList时递增,而不是在循环的每次迭代中递增。

答案 1 :(得分:0)

问题是变量index的增量,该增量正在创建空/未定义的元素。

例如:

  • Array = [1];
  • index = 1
  • 回调返回false
  • 索引增加1 -> index = 2`
  • 下一次迭代回调返回true
  • 在位置Array 2
  • ->添加了新元素
  • Array = [1, undefined, 3]

为newArray使用单独的索引。



class List {
  constructor(values = []) {
    this._list = values;
  }

  filter(func) {
    let newList = new Array();
    let index = 0;
    let newListIndex = 0;

    while (this._list[index] != undefined) {
      if (func(this._list[index]) === true) {
        newList[newListIndex++] = (this._list[index]);
      }
      index++;
    }
    this._list = newList;
    return this;
  }

  get values() {
    return this._list
  }
}

var isOdd = function(x) {
  return x % 2 === 1;
};

var list = new List([1, 2, 3, 4, 5]);
console.log(list.filter(isOdd));




答案 2 :(得分:0)

我建议坚持使用array#filter的函数式编程风格定义,因为这是它源自的范例。

这是List#filter的完全不可变版本,您可以在其中获得List的新实例,并且底层数组永远不会经历任何形式的突变。



class List {
  constructor(values = []) {
    this._list = values;
  }

  filter(func) {
    var reduce = function(values, accum) {
      if(values.length === 0) return accum;
      if(func(values[0])) return reduce(values.slice(1), accum.concat(values[0]));
      else return reduce(values.slice(1), accum)
    }
    return new List(reduce(this._list, []))
  }

  get values() {
    return this._list
  }
}

var isOdd = function(x) {
  return x % 2 === 1;
};

var list = new List([1, 2, 3, 4, 5]);
console.log(list.filter(isOdd));