我有一个看起来像这样的JavaScript对象。它基本上是我从某个API获得的输出。该对象的结构使得它可以包含多个相同'权益的实例。 (见下面的Hitachi Home):
{
"results": {
"holdings": [{
"equity": {
"text": "Hitachi Home"
},
"holding_pc": "6.48",
"sector": "Consumer Durables",
"shares_no": "1537.00",
"value_cr": "0.24"
}, {
"equity": {
"text": "Mahindra CIE"
},
"holding_pc": "6.34",
"sector": "Manufacturing",
"shares_no": "10376.00",
"value_cr": "0.24"
}, {
"equity": {
"text": "Schneider Infra"
},
"holding_pc": "5.33",
"sector": "Utilities",
"shares_no": "9518.00",
"value_cr": "0.20",
}, {
"equity": {
"text": "Hitachi Home"
},
"holding_pc": "2.18",
"sector": "Consumer Durables",
"shares_no": "437.00",
"value_cr": "0.12"
}]
}
}
编写将整个对象作为输入的JavaScript函数的最佳方法是什么,迭代所有记录并合并它以使具有相同'权限的记录总结和巩固。例如,在产出中,股权' Hitachi Home'应该看起来像这样:
{
"results": {
"holdings": [{
"equity": {
"text": "Hitachi Home"
},
"holding_pc": "8.66",
"sector": "Consumer Durables",
"shares_no": "1974.00",
"value_cr": "0.36"
}, {
"equity": {
"text": "Mahindra CIE"
},
"holding_pc": "6.34",
"sector": "Manufacturing",
"shares_no": "10376.00",
"value_cr": "0.24"
}, {
"equity": {
"text": "Schneider Infra"
},
"holding_pc": "5.33",
"sector": "Utilities",
"shares_no": "9518.00",
"value_cr": "0.20",
}]
}
}
基本上,我正在尝试编写一个JS函数,它将使用相同的文本汇总所有股票。以下是我们的主要目标:
function transform(data) {
function sumHoldings(row) {
newrow = {};
newrow.equity = row.equity.text;
newrow.holding_pc = row.holding_pc;
return newrow;
}
for(var holdings in data.results) {
data.results.total_holdings = data.results.holdings.map(sumHoldings);
};
return data;
}
答案 0 :(得分:1)
我建议制作一个可以合并数据的馆藏对象,并且可以通过馆藏名称访问(我认为这里是独一无二的)。
通过这种方式,您可以遍历您的馆藏阵列并将原始对象的数据分配给新对象,通常如下所示:
var consolidatedHoldings = {};
obj.results.holdings.forEach(function(holding){
holding.forEach(function (holdingDataValue, holdingDataIndex) {
// checking if the value is a number
if (!isNaN(parseFloat(holdingDataValue)) && isFinite(holdingDataValue)) {
consolidatedHoldings[holdingDataIndex] = consolidatedHoldings[holdingDataIndex] + parseFloat(holdingDataValue);
} else {
consolidatedHoldings[holdingDataValue] = holdingDataValue;
}
});
});
这样,如果密钥不存在,它就会被创建。如果它被覆盖(预期具有相同的值)。如果这是一个数字,它会被添加。
您最终得到一个合并的馆藏对象,然后您可能想要变成一个阵列并放入原始对象。
答案 1 :(得分:1)
var map = {};
a.holdings.forEach(function(holding){
var text = holding.equity.text;
var entry = map[text] || (map[text] = []);
entry.push(holding);
});
Object.keys(map).map(function(key) {
var values = map[key];
var parseFloats = function(a, b) { return parseFloat(a) + parseFloat(b); };
return {
equity: {
"text" : key
},
sector : values[0].sector,
value_cr: values.map(function(e) { return e.value_cr; }).reduce(parseFloats, 0),
shares_no: values.map(function(e) { return e.shares_no; }).reduce(parseFloats, 0),
holding_pc : values.map(function(e) { return e.holding_pc; }).reduce(parseFloats, 0)
}
});
答案 2 :(得分:1)
您可以按如下方式缩小原始数组:
var obj = {
"results": {
"holdings": [{
"equity": {
"text": "Hitachi Home"
},
"holding_pc": "6.48",
"sector": "Consumer Durables",
"shares_no": "1537.00",
"value_cr": "0.24"
}, {
"equity": {
"text": "Mahindra CIE"
},
"holding_pc": "6.34",
"sector": "Manufacturing",
"shares_no": "10376.00",
"value_cr": "0.24"
}, {
"equity": {
"text": "Schneider Infra"
},
"holding_pc": "5.33",
"sector": "Utilities",
"shares_no": "9518.00",
"value_cr": "0.20",
}, {
"equity": {
"text": "Hitachi Home"
},
"holding_pc": "2.18",
"sector": "Consumer Durables",
"shares_no": "437.00",
"value_cr": "0.12"
}]
}
}
function findFirst(items, predicate) {
for (var i = 0; i < items.length; i++) {
if (predicate(items[i])) {
return items[i];
}
}
return null;
}
var result = obj.results.holdings.reduce(function (arr, it) {
it.holding_pc = Number(it.holding_pc);
it.shares_no = Number(it.shares_no);
it.value_cr = Number(it.value_cr);
var holding = findFirst(arr, function (_it) { return _it.equity.text === it.equity.text });
if (holding) {
// If item is found make calculations
holding.holding_pc += it.holding_pc;
holding.shares_no += it.shares_no;
holding.value_cr += it.value_cr;
} else {
// If item is not found aded to the array
arr.push(it);
}
return arr;
}, []);
document.querySelector('#out').innerHTML = JSON.stringify({ results: { holdings: result } }, undefined, 4);
<pre id="out"></pre>
答案 3 :(得分:0)
您应该迭代数组,而不是对象。除非您对迭代对象的属性感兴趣。类似的东西:
obj.results.holdings.forEach(function(holding){
//holding.equity.text holds the equity string.
//It's up to you how to deal with the uniqueness.
//You could just push it into an array if the equity.text value isn't within the array.
});
编辑:我想你想要减少数组,而不是找到唯一的。
var equity = { };
var sums = ['holding_pc', 'shares_no', 'value_cr'];
var holdings = obj.results.holdings.reduce(function(previousValue, currentValue){
var currentEquity = currentValue.equity.text;
if(equity[currentEquity] !== undefined){
//Equity exists in reduced array
oldObj = previousValue[equity[currentEquity]];
sums.forEach(function(prop){
oldObj[prop] = Number(oldObj[prop]) + Number(currentValue[prop]);
});
} else {
//Equity doesn't exist
equity[currentEquity] = previousValue.length;
previousValue.push(currentValue);
}
return previousValue;
}, []);
//holdings is now a reduced array (not the result object, result.holdings array).