2017-01-20 1 views
3

Ich habe den ganzen Tag mit diesem Problem gekämpft.Underscore Map Objekt

Ich habe folgendes Array bekam:

controller.array = [{ 
    Equity: "0", 
    Bond: "97.42", 
    Cash: "67.98" 
}, { 
    Equity: "5.32", 
    Bond: "13.12", 
    Cash: "8" 
}, { 
    // ... 
} /* ... */ ] 

Was soll ich tun, um ein einzelnes Array erstellen Objekte mit kombinierten Werte wie so enthält:

controller.newArray = [{ 
    Type: "Equity", 
    Percentage: "5.32" 
}, { 
    Type: "Bond", 
    Percentage: "110.54" 
}, { 
    Type: "Cash", 
    Percentage: "75.98" 
} /* ... */ ] 

Ich habe versucht, _.each wie folgt aus :

.map(function(item, value) { 
    var array = []; 
    _.each(item, function(value, item) { 
     array.push({ 
     'Source': item, 
     'Percentage': value 
     }) 
    }) 
    return array; 
    }) 
    .value() 

Was dann passiert ist, dass es ein Array zurückgibt, das mu enthält Kleinere Arrays mit Objekten mit meinen Werten. Jetzt ist mein Problem, dass ich nicht scheinen kann, alle Arrays zu kombinieren, die zurückgegeben werden.

Irgendwelche Ideen? Bitte?

+0

Können Sie ein minimales, vollständiges und überprüfbares Beispiel (http://stackoverflow.com/help/mcve) angeben. Verwenden Sie das ausführbare Code-Snippet. – ppasler

+1

Ich glaube, seine Frage ist völlig klar @ppasler - er fragt nicht um Hilfe bei einem Problem, sondern mehr darüber, wie man sie löst. Er möchte das erste Array (mehrere Objekte mit den Eigenschaften "Equity", "Bond" und "Cash") in das zweite Array umwandeln. –

+0

@JamesMonger war mir nicht klar und ich mag es immer, wenn ein laufendes Beispiel bereitgestellt wird. Keine anderen müssen es zu einem laufenden Beispiel machen. – ppasler

Antwort

5

Sie können die Anordnung von Objekten in einem Array von Werten durch ihre gemeinsamen Schlüssel gruppiert transponieren.

Dann können Sie die Werte den resultierenden Objekten zuordnen. Die Funktionen transpose() und sum() sind Unterstreichungs-Mixins, also können Sie sie verketten!

_.mixin({ 
 
    transpose : function(array) { 
 
    return _.chain(array).map(_.keys).flatten().uniq().reduce(function(result, key) { 
 
     result[key] = _.pluck(array, key); 
 
     return result; 
 
    }, {}).value(); 
 
    }, 
 
    sum : function(values) { 
 
    return _.reduce(values, function(sum, value) { 
 
     return sum + (_.isNumber(value) ? value : parseFloat(value)); 
 
    }, 0); 
 
    } 
 
}); 
 

 
var array = [{ 
 
    Equity: "0", 
 
    Bond: "97.42", 
 
    Cash: "67.98" 
 
}, { 
 
    Equity: "5.32", 
 
    Bond: "13.12", 
 
    Cash: "8" 
 
}]; 
 

 
var result = _.chain(array).transpose().map(function(value, key) { 
 
    return { 
 
    Type: key, 
 
    Percentage: _.sum(value).toFixed(2) 
 
    }; 
 
}).value(); 
 

 
console.log(JSON.stringify(result, null, 2));
.as-console-wrapper { top: 0; max-height: 100% !important; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min.js"></script>

0

Wenn das, was Sie brauchen, ist jede Art zusammenzufassen dann sollte dies tun:

keys = {Equity: 0, Bond: 0, Cash: 0} 
//newArray is the array from your question 
newArray.forEach(function(obj) { 
    keys[obj.Type] += obj.Percentage}) 
2

Eine Möglichkeit, nur mit JavaScript könnte map und reduce Funktionen zu benutzen:

var data = [{Equity: "0", Bond: "97.42", Cash: "67.98"}, 
 
      {Equity: "5.32", Bond: "13.12", Cash: "8"}]; 
 

 
var sumMap = data.reduce(function(acc, item) { 
 
    Object.keys(item).forEach(function(itemKey) { 
 
    if (acc[itemKey] === undefined) { 
 
     acc[itemKey] = 0; 
 
    } 
 
    acc[itemKey] += parseFloat(item[itemKey]); 
 
    }); 
 
    return acc; 
 
}, {}); 
 
var result = Object.keys(sumMap).map(function(itemKey) { 
 
    return { 
 
    "Type": itemKey, 
 
    "Percentage": "" + sumMap[itemKey] 
 
    }; 
 
}); 
 

 
console.log(JSON.stringify(result, null, 2));

Das Zwischenergebnis sumMap so etwas wie dies sein wird, :

{ 
    Equity: 5.32, 
    Bond: 110.54, 
    Cash: 75.98 
} 

Die fiddle (dank CPHPython).

+0

Schöne Vanille-Lösung, aber Sie könnten stattdessen parseFloat verwenden, hier ist eine [Geige] (https://jsfiddle.net/jL4y36cd/) (öffnen Sie die Konsole zuerst zum Testen). Korrigiere die Antwort, füge ein laufendes Snippet hinzu und ich werde upvote. – CPHPython

+0

danke! :) haha, ich weiß nicht warum ich 'parseInt' benutze, schöner Fang! :) – andrusieczko