簡體   English   中英

如何對數組中的對象使用javascript reduce函數獲取字符串值

[英]How to use javascript reduce function for objects in an array to get string values

我有一個對象數組,我想從中獲取名稱。 我正在嘗試使用reduce,但是問題是reduce會將未定義的第一個值返回,並且僅返回數組中的最后一個值。 我不知道這是為什么? reduce如何處理對象內部的字符串?

我的代碼:

    var data = [ {name: 'Bart'}, {name: 'Lisa'}, {name: 'Maggie'} ]

    var result = function(){

    var names = data.reduce(function(a, b){
    return  a.name + ',' + b.name
    })
    return names

    };

    var res = result();
    console.log(res)

**`output // undefined,Maggie`**

小提琴

像這樣:

var names = data.reduce(function (names, item) {
  return names + ' ' + item.name;
}, "");

要么:

var names = data.map(function (item) { return item.name }).join(" ");

Reduce對數組中存在的每個元素執行一次回調函數,不包括數組中的孔。

前兩個參數是:累加器(在您的情況下為a )currentValue(在您的情況下為b

沒有提供InitialValue ,因此reduce將從索引1開始執行回調函數,跳過第一個索引。 第一次是累加器是對象{name: 'Bart'} ,第二次是字符串"Bart,Lisa"

  var data = [ {name: 'Bart'}, {name: 'Lisa'}, {name: 'Maggie'} ] var result = function(){ var names = data.reduce(function(a, b){ return (a.name || a) + ',' + b.name }) return names }; var res = result(); console.log(res) 

對於更干凈的解決方案,您可以使用map而不是reduce。(可讀性更高)

 var data = [ {name: 'Bart'}, {name: 'Lisa'}, {name: 'Maggie'} ] var result = data.map(x =>x.name).join(","); console.log(result); 

reduce需要兩個參數。 第一個是累加值,第二個是數組中的元素之一。 首先,使用提供的累加器,在我的示例中為空字符串。 我想提供的將是undefined的空值。

arrData.reduce(function (strAccumulator, objElement) {
    return (strAccumulator ? strAccumulator + ', ' : '' ) + objElement.name;
}, "");
// ==> "Bart, Lisa, Maggie"

如果您使用Underscore,則可以通過pluck 加入以下清潔劑:

_.pluck(arrData, 'name').join(', ');
// ==> "Bart, Lisa, Maggie"

請注意,如果您的對象具有toString函數,該函數返回您想要的字符串表示形式,則可以省略以下操作:

function Simpson(strName) {
  this.name = strName;
}
Simpson.prototype.toString = function(){
  return this.name;
};
var arrData = [new Simpson('Bart'), new Simpson('Lisa'), new Simpson('Maggie')];

arrData.join(', ');
// ==> "Bart, Lisa, Maggie"

為什么和如何

這里有幾個答案急於使答案正確,但是卻無法建立強大而完整的功能。 這個答案是詳盡無遺的,它使您了解為什么我們會選擇某些實現而不是其他實現


合同

為了讓您的函數能夠在所有[{name: String}]輸入上運行( 應該 ),您必須處理3種情況

listofNames([])                                   // ''
listofNames([{name: 'Bart'}])                     // 'Bart'
listofNames([{name: 'Bart'},{name: 'Lisa'}, ...]) // 'Bart, Lisa, ...'
  1. 一個空數組( [] )返回一個空字符串
  2. 單個名稱只會返回該名稱– ', '不存在分隔符
  3. 包含2個或更多名稱的數組將返回名稱,並在名稱之間使用分隔符

滿足您的要求

您要求使用Array.prototype.reduce進行此操作,因此我們將從此處開始。 您會注意到,這個答案是

  • 它適用於上述所有輸入方案,使listOfNames成為一個整體函數 –其他幾個答案無法容納上述( 1 )和( 2 )。
  • 它僅使用一個單一的 if ,因為這是所有需要-使用if內減速浪費*

 const listOfNames = ([x,...xs]) => { if (x === undefined) return '' else return xs.reduce((acc, {name}) => acc + ', ' + name, x.name) } console.log(listOfNames([])) // '' console.log(listOfNames([{name: 'Bart'}])) // 'Bart' console.log(listOfNames([{name: 'Bart'}, {name: 'Lisa'}])) // 'Bart, Lisa' 


一個推薦

您使用函數式編程標記了這個問題,所以我們將從另一個角度來看這個問題。 上面我們做的是重新發明Array.prototype.join函數-實際上只有我們更糟

 console.log([].join(', ')) // '' console.log(['Bart'].join(', ')) // 'Bart' console.log(['Bart','Lisa'].join(', ')) // 'Bart, Lisa' 

我們的函數更加具體,不允許我們更改使用的分隔符(始終使用', ' ),並且假定數組中的每個元素都有一個name屬性。

在函數式編程的天堂里,我們應該使我們的函數盡可能通用 -這可以最大程度地回收代碼。

好的,所以我們不需要重新構造一個完美的函數,只需要將對象數組轉換為名稱數組,然后使用完美的join函數

 const prop = x => y => y[x] const listOfNames = xs => xs.map(prop('name')).join(', ') console.log(listOfNames([])) // '' console.log(listOfNames([{name: 'Bart'}])) // 'Bart' console.log(listOfNames([{name: 'Bart'}, {name: 'Lisa'}])) // 'Bart, Lisa' 


“但是其他人說的基本上是一樣的。”

是的,但是顯然他們不知道為什么會更好。 他們認為,因為生成的代碼更短,所以它會更好-否則,他們也不會提供reduce解決方案,這些解決方案是如此的復雜/不完整。

現在您知道了為什么某些解決方案比其他解決方案更好,並且可以評估哪種解決方案最適合您

測驗:你能說出一個原因map + join的解決辦法是不如我們的定制reduce解決方案嗎?

您需要檢查是否設置了先前的值(a)。 如果沒有返回當前值(b)。 還要傳入一個空字符串作為reduce函數的初始值。

var data = [ {name: 'Bart'}, {name: 'Lisa'}, {name: 'Maggie'} ]

var result = function(){
    var names = data.reduce(function(a, b){
        return  a ? a + ',' + b.name : b.name;
    },"");
    return names;
};
var res = result();
console.log(res);

暫無
暫無

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

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