[英]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, ...'
[]
)返回一個空字符串 ', '
不存在分隔符 滿足您的要求
您要求使用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.