繁体   English   中英

重写Javascript过滤器/ 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}..

如果您想知道它们的作用, 则说明很明确 ,可以合理地将其转换为JavaScript代码(实际上,这是在MDN上完成的 )。

您和JavaScript之间的一些区别:

  1. JavaScript的forEachfilter 使用for-in ,这是您和JavaScript之间的根本区别。 他们只使用对象和数组索引,期望对象类似于数组 (例如,具有length和属性的键,例如"0""1" ,[等等,所有键都是字符串,甚至标准阵列中的键,这些键根本不是真正的阵列)。

  2. JavaScript的版本不会调用不存在的条目的回调(例如,在稀疏数组的情况下)。 要将其添加到您的数据库中,请在某个阶段添加hasOwnProperty(index)

  3. JavaScript的版本将更多参数传递给回调。

  4. JavaScript的版本允许您指定一个值,以在调用回调时用作this值。

  5. JavaScript的版本会在开始之前获取长度,因此,如果修改了集合,则会使用旧的长度。 根据更改的位置,可能会跳过条目。

因此,例如,您对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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM