簡體   English   中英

使用Reduce將數組轉換為對象

[英]Converting Array to Object using Reduce

有人可以解釋這是如何工作的。

學習使用Array.reduce()

var votes = ['tacos','pizza','pizza','tacos','fries','ice cream','ice cream','pizza'];

var initialValue = {}

var reducer = function(tally, vote) {
  if (!tally[vote]) {
      tally[vote] = 1;
  } else {
      tally[vote] = tally[vote] + 1;
  }
      return tally;
  }

var result = votes.reduce(reducer, initialValue)

reduce的工作方式與mapfilter非常相似。 在這種情況下,reducer負責對象數組簡化為一個對象。

reducer函數遍歷數組的所有元素。 該函數使用兩個參數調用, tally 到目前為止減少的結果當前正在處理的 vote 數組元素

如果tally沒有像當前正在處理/縮減的元素那樣命名的屬性,則它將這樣的鍵添加到對象並將其值設置為1。 否則(存在密鑰),它將增加一。

欲了解更多信息,請點擊這里

基本上, Array.prototype.reduce()方法對一個累加器和數組的每個值應用一個函數,以將其減少為單個值。

在您的示例中,將減小的值(計數操作的結果)分配為稱為tally的對象的屬性,該對象由.reduce()返回;

我用簡短的解釋評論您:

 // your data in an array var votes = ['tacos','pizza','pizza','tacos','fries','ice cream','ice cream','pizza']; // optional value to use as the first argument to the first call of the callback when using Array.prototype.reduce(). var initialValue = {} // tally = previousValue and vote = currentValue var reducer = function(tally, vote) { // if tally is not assign as a key in tally object, add key and add value of one, (basically count 1 for one element in your votes array) if (!tally[vote]) { tally[vote] = 1; } else { // otherwise if tally object has already this key, increment its value by one, (basically it counts how many times each item in votes array is present in the array) tally[vote] = tally[vote] + 1; } return tally; } var result = votes.reduce(reducer, initialValue); console.log(result); 

注意:實際上,您可以避免使用為initialValue聲明變量,而只使用var result = votes.reduce(reducer, {});

API文檔:

https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/Reduce

更多示例和簡要說明:

https://www.airpair.com/javascript/javascript-array-reduce

我在您的代碼中插入了一些console.log消息,這有助於我了解發生了什么。

 var votes = ['tacos', 'pizza', 'pizza', 'tacos', 'fries', 'ice cream', 'ice cream', 'pizza']; var initialValue = {} var reducer = function(tally, vote) { console.log("tally: ", tally); console.log("vote: ", vote); console.log("tally[vote]: ", tally[vote]); if (!tally[vote]) { tally[vote] = 1; } else { tally[vote] = tally[vote] + 1; } return tally; } var result = votes.reduce(reducer, initialValue) console.log("result: " + JSON.stringify(result)); 

在這里和其他地方有很多關於reduce的冗長解釋,但我認為簡單的視覺演示可能會有所幫助

[1,2,3].reduce(function(a,b) { return a + b }, 0)
// (((0 + 1) + 2) + 3)
// => 6

您可以看到:

  • 3個元素的輸入列表將導致3次計算
  • 初始值用於第一個元素的計算
  • 一個計算的結果將在下一個計算中使用…
  • …直到最后的計算,這是reduce的結果

現在,對於您的代碼,我們並沒有建立數字的總和,而是建立了一個Object ,它保存數組中每個字符串的計數計數。

我沒有必要解釋其他所有人的所作所為,但這不足為奇,這並不奇怪,因為沒有人解釋這是對Object的濫用。

實際上,對於這種簡化,對象實際上不是最佳的數據結構選擇。 在這里,對象用於模擬Map的行為。

我們將initialValue設置為new Map()然后您將了解reducer如何在其中使用更多描述性語法。 注意注釋甚至不是必需的,因為代碼說明了它所需要的一切。

 var votes = ['tacos','pizza','pizza','tacos','fries','ice cream','ice cream','pizza'] var initialValue = new Map() var reducer = function (tally, vote) { if (tally.has(vote)) return tally.set(vote, tally.get(vote) + 1) else return tally.set(vote, 1) } var result = votes.reduce(reducer, initialValue) console.log(Array.from(result.entries())) 

輸出量

[
  [ "tacos", 2 ],
  [ "pizza", 3 ],
  [ "fries", 1 ],
  [ "ice cream", 2 ]
]

只是為了好玩

我可以通過編寫一個構造字符串而不是實際將數字相加的reduce來向您展示通過reduce進行的總和的視覺表示是正確/准確的

 var initialValue = 0 var reducer = function(a,b) { return '(' + a + ' + ' + b + ')' } var result = [1,2,3].reduce(reducer, initialValue) console.log(result) // (((0 + 1) + 2) + 3) 

嘗試了解/調試自己的Reducer時,此技術可能對您有用

reduce()方法數組縮小單個值

reduce()方法為數組的每個值從左到右 執行 提供的函數

函數的返回值 存儲在累加器中(結果/總計)。

您有此給定列表

var votes = ['tacos','pizza','pizza','tacos','fries','ice cream','ice cream','pizza'];

然后創建一個初始列表 您可以對此進行修改,並且該功能將同時應用於兩個列表。

var initialValue = {}

“ reducer”被初始化為一個函數 之所以將函數放置在“ reducer”中,是因為我們可以更輕松地對其進行調用。 您可以在此函數中做任何您想做的事,它將在接下來的步驟中在列表中執行

var reducer = function(tally, vote) {
  if (!tally[vote]) {
      tally[vote] = 1;
  } else {
      tally[vote] = tally[vote] + 1;
  }
      return tally;
  }

最后,函數的結果 存儲到變量中。

var result = votes.reduce(reducer, initialValue)

好吧,讓我們嘗試擴展迭代:

執行時

votes.reduce(reducer, initialValue)

它實際上是這樣做的:

reducer(initialValue, votes[0]); // step1, return {'tacos': 1}
reducer(returnedValueOfStep1, votes[1]); // step2, return {'tacos': 1, 'pizza': 1}
reducer(returnedValueOfStep2, votes[2]); // step3, return {'tacos': 1, 'pizza': 2}
reducer(returnedValueOfStep3, votes[3]); // step4 ...
reducer(returnedValueOfStep4, votes[4]); // step5 ...
reducer(returnedValueOfStep5, votes[5]); // step6 ...
reducer(returnedValueOfStep6, votes[6]); // step7 ...
reducer(returnedValueOfStep7, votes[7]); // step8 ...

我認為現在很清楚。

通常,如果我們不提供initialValue作為reduce的第二個參數,它將數組的第一個元素作為initialValue,並從第二個元素開始迭代:

reducer(votes[0], votes[1]); // step1 ...
reducer(returnedValueOfStep1, votes[2]); // step2 ...
...

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM