重写 Javascript filter / forEach
Rewriting Javascript filter / forEach
Javascript 的新手 - 我正在尝试重写 forEach 和过滤器以理解它们。我希望能够使用过滤器来传递类似 {"hello": 4, "world": 2, "hi": 1} 的内容,并能够根据数字进行过滤。
这是我的 forEach:
function myForEach(collection, callback) {
if (Array.isArray(collection)) {
for (var i = 0; i < collection.length; i++) {
callback(collection[i]);
}
}
else {
for (var key in collection) {
callback(collection[key]);
}
}
}
这是过滤器:
function filterWithForEach (collection, predicate) {
if (Array.isArray(collection)) {
var newArray = [];
myForEach(collection, function (element) {
if (predicate(element)) {
newArray.push(element);
}
});
return newArray;
}
else {
var newCollection = {};
myForEach(collection, function (element) {
if (predicate(element)) {
newCollection[element] = element; //here's where I think it's wrong
}
});
return newCollection;
}
}
我知道问题在于我如何分配它们,因为当我测试它时我得到这些输出:
console.log(filterWithForEach([1,2,3,4,5], function(num) {
return num > 2;
})); // works fine
console.log(filterWithForEach(aList, function(item) {
return item > 3;
})); // provides {4: 4}..
如果你想知道他们做什么,the spec is fairly clear and can pretty reasonably be turned into JavaScript code (in fact, that's been done on MDN)。
你的和 JavaScript 的一些区别:
JavaScript的forEach
和filter
不要使用for-in
,这是你和JavaScript的根本区别。他们只使用对象和数组索引,期望对象是一个 类数组 (例如,有一个 length
和带有 "0"
等键的属性, "1"
,依此类推[是的,所有的键都是字符串,甚至是标准数组中的键,它们根本不是真正的数组]。
JavaScript 的版本不会为不存在的条目调用回调(例如,在稀疏数组的情况下)。要将其添加到您的,您需要在某个阶段添加 hasOwnProperty(index)
。
JavaScript 的版本将更多参数传递给回调。
JavaScript 的版本允许您在调用回调时指定一个值作为 this
使用。
JavaScript的版本在开始前就抢了长度,所以如果修改了collection,还是用旧的长度。根据更改的位置,条目可能会被跳过。
例如,您对 forEach
的看法可能更像是这样:
function myForEach(collection, callback, thisArg) {
var l = +collection.length;
for (var i = 0; i < l; i++) {
if (collection.hasOwnProperty(i)) {
callback.call(thisArg, collection[i], i, collection);
}
}
}
同样,不是(远程)规范中算法的准确实现,只是对您的算法稍作修改以解决我上面提出的具体点。
如果您正在寻找要返回的对象,那么这就是它应该的方式。
function myForEach(collection, callback) {
if (Array.isArray(collection)) {
for (var i = 0; i < collection.length; i++) {
callback(collection[i]);
}
}
else {
for (var key in collection) {
callback(collection[key], key);
}
}
}
这是过滤器:
function filterWithForEach (collection, predicate) {
if (Array.isArray(collection)) {
var newArray = [];
myForEach(collection, function (element) {
if (predicate(element)) {
newArray.push(element);
}
});
return newArray;
}
else {
var newCollection = {};
myForEach(collection, function (element,key) {
if (predicate(element)) {
newCollection[key] = element; }
});
return newCollection;
}
}
您可以在 Array 原型函数中创建一个过滤器自己的方法。如果您正在寻找不同的方法,您可以使用迭代器和这样的递归函数:
Array.prototype.megaFilter = function(cb) {
const iterator = this[Symbol.iterator]();
const iteration = iterator.next();
const filteredArray = [];
iterate(iteration);
function iterate(iteration) {
if (iteration.done) return iteration;
if (cb(iteration.value)) filteredArray.push(iteration.value);
const nextIteration = iterator.next(iteration.value);
return iterate(nextIteration);
}
return filteredArray;
};
const array = [1, 2, 3, 4, 5, 6, 7];
console.log(array.megaFilter(v => v % 2 === 0));
大纲就到这里了,欢迎大家多提意见:
https://gist.github.com/jdtorregrosas/d69f67e8079f82fbc2a5904e76a8fb6c
Javascript 的新手 - 我正在尝试重写 forEach 和过滤器以理解它们。我希望能够使用过滤器来传递类似 {"hello": 4, "world": 2, "hi": 1} 的内容,并能够根据数字进行过滤。
这是我的 forEach:
function myForEach(collection, callback) {
if (Array.isArray(collection)) {
for (var i = 0; i < collection.length; i++) {
callback(collection[i]);
}
}
else {
for (var key in collection) {
callback(collection[key]);
}
}
}
这是过滤器:
function filterWithForEach (collection, predicate) {
if (Array.isArray(collection)) {
var newArray = [];
myForEach(collection, function (element) {
if (predicate(element)) {
newArray.push(element);
}
});
return newArray;
}
else {
var newCollection = {};
myForEach(collection, function (element) {
if (predicate(element)) {
newCollection[element] = element; //here's where I think it's wrong
}
});
return newCollection;
}
}
我知道问题在于我如何分配它们,因为当我测试它时我得到这些输出:
console.log(filterWithForEach([1,2,3,4,5], function(num) {
return num > 2;
})); // works fine
console.log(filterWithForEach(aList, function(item) {
return item > 3;
})); // provides {4: 4}..
如果你想知道他们做什么,the spec is fairly clear and can pretty reasonably be turned into JavaScript code (in fact, that's been done on MDN)。
你的和 JavaScript 的一些区别:
JavaScript的
forEach
和filter
不要使用for-in
,这是你和JavaScript的根本区别。他们只使用对象和数组索引,期望对象是一个 类数组 (例如,有一个length
和带有"0"
等键的属性,"1"
,依此类推[是的,所有的键都是字符串,甚至是标准数组中的键,它们根本不是真正的数组]。JavaScript 的版本不会为不存在的条目调用回调(例如,在稀疏数组的情况下)。要将其添加到您的,您需要在某个阶段添加
hasOwnProperty(index)
。JavaScript 的版本将更多参数传递给回调。
JavaScript 的版本允许您在调用回调时指定一个值作为
this
使用。JavaScript的版本在开始前就抢了长度,所以如果修改了collection,还是用旧的长度。根据更改的位置,条目可能会被跳过。
例如,您对 forEach
的看法可能更像是这样:
function myForEach(collection, callback, thisArg) {
var l = +collection.length;
for (var i = 0; i < l; i++) {
if (collection.hasOwnProperty(i)) {
callback.call(thisArg, collection[i], i, collection);
}
}
}
同样,不是(远程)规范中算法的准确实现,只是对您的算法稍作修改以解决我上面提出的具体点。
如果您正在寻找要返回的对象,那么这就是它应该的方式。
function myForEach(collection, callback) {
if (Array.isArray(collection)) {
for (var i = 0; i < collection.length; i++) {
callback(collection[i]);
}
}
else {
for (var key in collection) {
callback(collection[key], key);
}
}
}
这是过滤器:
function filterWithForEach (collection, predicate) {
if (Array.isArray(collection)) {
var newArray = [];
myForEach(collection, function (element) {
if (predicate(element)) {
newArray.push(element);
}
});
return newArray;
}
else {
var newCollection = {};
myForEach(collection, function (element,key) {
if (predicate(element)) {
newCollection[key] = element; }
});
return newCollection;
}
}
您可以在 Array 原型函数中创建一个过滤器自己的方法。如果您正在寻找不同的方法,您可以使用迭代器和这样的递归函数:
Array.prototype.megaFilter = function(cb) {
const iterator = this[Symbol.iterator]();
const iteration = iterator.next();
const filteredArray = [];
iterate(iteration);
function iterate(iteration) {
if (iteration.done) return iteration;
if (cb(iteration.value)) filteredArray.push(iteration.value);
const nextIteration = iterator.next(iteration.value);
return iterate(nextIteration);
}
return filteredArray;
};
const array = [1, 2, 3, 4, 5, 6, 7];
console.log(array.megaFilter(v => v % 2 === 0));
大纲就到这里了,欢迎大家多提意见: https://gist.github.com/jdtorregrosas/d69f67e8079f82fbc2a5904e76a8fb6c