簡體   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