合并和数量添加 javascript 个对象
merge and quantity add javascript objects
您好,我有以下内容:
> var gb = [{"sku": "EP01", "qty": 10, "cntry": "GB"}, {"sku": "EP02", "qty": 5, "cntry": "GB"}, {"sku": "EP03", "qty": 15, "cntry": "GB"}];
>
> var de = [{"sku": "EP01", "qty": 100, "cntry": "DE"}, {"sku": "EP02", "qty": 25, "cntry": "DE"}];
> var obj1 = gb.concat(de);
[ { sku: 'EP01', qty: 100, cntry: 'DE' },
{ sku: 'EP02', qty: 25, cntry: 'DE' },
{ sku: 'EP03', qty: 15, cntry: 'GB' },
{ sku: 'EP01', qty: 100, cntry: 'DE' },
{ sku: 'EP02', qty: 25, cntry: 'DE' } ]
>
这是错误的,因为我得到两个 { sku: 'EP01', qty: 100, cntry: 'DE' }
,而我想得到一个合并对象,例如 { sku: 'EP01', total: 110, qty-gb: 10, qty-de: 100 }
我的列表有大约 8,000 个条目,在某些情况下,一个条目可能存在于一个条目中,但另一个条目不存在。
在 node.js 上使用 lodash 实现此目的的有效方法是什么?
我试过这个:
allStockAPI = exports.allStockAPI = (req) ->
Promise.props
stocksAPI: stockAPI(req)
germanStocks: germanStocks.getStocks(config.germanStocksUrl)
.then (result) ->
newDe = result.germanStocks.map (i) ->
return Object.values(i)
result.stocksAPI.forEach (i) ->
i.pop()
rows = result.stocksAPI.concat newDe
#console.log rows
skus = rows.map (row) ->
{
sku: row[0],
val: row
}
groupedRows = _(skus).groupBy('sku').value()
rows = _(Object.keys(groupedRows)).uniq().value().map (sku) ->
rows = groupedRows[sku].map (row) ->
row.val
rows = rows.map (row) ->
if row[row.length - 2]
row[row.length - 2] = row[row.length - 1] + ' office : ' + row[row.length - 2]
if row[row.length - 2] == null
row[row.length - 2] = ''
row
stock = rows.reduce (prev, cur) ->
prev[prev.length - 1] = 'UK/DE'
if (prev[prev.length - 2])
prev[prev.length - 2] = prev[prev.length - 2] + '<br>' + cur[prev.length - 2]
else
prev[prev.length - 2] = cur[prev.length - 2]
prev
stock
rows
但不正确
注意:我不知道如何将下面的代码更改为 coffescript,所以我将在 javascript 中回答这个问题。
您可以执行以下操作:
- 使用 groupBy() 按
sku
对项目进行分组。
- map() the grouped items and return the transformed
qty
keys by country through reduce() and the total
value through sumBy().
var gb = [{"sku": "EP01", "qty": 10, "cntry": "GB"}, {"sku": "EP02", "qty": 5, "cntry": "GB"}, {"sku": "EP03", "qty": 15, "cntry": "GB"}];
var de = [{"sku": "EP01", "qty": 100, "cntry": "DE"}, {"sku": "EP02", "qty": 25, "cntry": "DE"}];
var result = _(gb)
.concat(de)
.groupBy('sku')
.map(function(items) {
return _.reduce(items, function(acc, item) {
return _(item)
.omit(['qty', 'cntry'])
.set('qty-' + item.cntry, item.qty)
.assign(acc)
.value();
}, { total: _.sumBy(items, 'qty') });
})
.value();
document.write('<pre>' + JSON.stringify(result, 0, 4) + '</pre>');
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.12.0/lodash.js"></script>
一个简单的解决方案 Javascript,其中一个对象作为对插入对象元素的引用。
var gb = [{ "sku": "EP01", "qty": 10, "cntry": "GB" }, { "sku": "EP02", "qty": 5, "cntry": "GB" }, { "sku": "EP03", "qty": 15, "cntry": "GB" }],
de = [{ "sku": "EP01", "qty": 100, "cntry": "DE" }, { "sku": "EP02", "qty": 25, "cntry": "DE" }],
result = function (data) {
function update(a) {
if (!hash[a.sku]) {
hash[a.sku] = { sku: a.sku, total: 0 };
r.push(hash[a.sku]);
}
hash[a.sku]['qty-' + a.cntry.toLowerCase()] = a.qty;
hash[a.sku].total += a.qty;
}
var hash = Object.create(null),
r = [];
data.forEach(a => a.forEach(update));
return r;
}([gb, de]);
document.write('<pre>' + JSON.stringify(result, 0, 4) + '</pre>');
因为你在 Node 上,所有 ES6 的好东西都可以为你服务。所以我不会使用额外的库,如 lodash 或下划线。你可以这样做
var gb = [{"sku": "EP01", "qty": 10, "cntry": "GB"}, {"sku": "EP02", "qty": 5, "cntry": "GB"}, {"sku": "EP03", "qty": 15, "cntry": "GB"}],
de = [{"sku": "EP01", "qty": 100, "cntry": "DE"}, {"sku": "EP02", "qty": 25, "cntry": "DE"}];
merged = (...arrs) => arrs.reduce((p,c) => c.reduce((f,s) => f.concat(s),p),[]);
document.write("<pre>" + JSON.stringify(merged(gb,de),null,2) + "</pre>");
如果您怀疑可能会出现任何重复,最好始终在链的末尾应用过滤器。我也会实现那个,仅供参考。
您好,我有以下内容:
> var gb = [{"sku": "EP01", "qty": 10, "cntry": "GB"}, {"sku": "EP02", "qty": 5, "cntry": "GB"}, {"sku": "EP03", "qty": 15, "cntry": "GB"}];
>
> var de = [{"sku": "EP01", "qty": 100, "cntry": "DE"}, {"sku": "EP02", "qty": 25, "cntry": "DE"}];
> var obj1 = gb.concat(de);
[ { sku: 'EP01', qty: 100, cntry: 'DE' },
{ sku: 'EP02', qty: 25, cntry: 'DE' },
{ sku: 'EP03', qty: 15, cntry: 'GB' },
{ sku: 'EP01', qty: 100, cntry: 'DE' },
{ sku: 'EP02', qty: 25, cntry: 'DE' } ]
>
这是错误的,因为我得到两个 { sku: 'EP01', qty: 100, cntry: 'DE' }
,而我想得到一个合并对象,例如 { sku: 'EP01', total: 110, qty-gb: 10, qty-de: 100 }
我的列表有大约 8,000 个条目,在某些情况下,一个条目可能存在于一个条目中,但另一个条目不存在。
在 node.js 上使用 lodash 实现此目的的有效方法是什么?
我试过这个:
allStockAPI = exports.allStockAPI = (req) ->
Promise.props
stocksAPI: stockAPI(req)
germanStocks: germanStocks.getStocks(config.germanStocksUrl)
.then (result) ->
newDe = result.germanStocks.map (i) ->
return Object.values(i)
result.stocksAPI.forEach (i) ->
i.pop()
rows = result.stocksAPI.concat newDe
#console.log rows
skus = rows.map (row) ->
{
sku: row[0],
val: row
}
groupedRows = _(skus).groupBy('sku').value()
rows = _(Object.keys(groupedRows)).uniq().value().map (sku) ->
rows = groupedRows[sku].map (row) ->
row.val
rows = rows.map (row) ->
if row[row.length - 2]
row[row.length - 2] = row[row.length - 1] + ' office : ' + row[row.length - 2]
if row[row.length - 2] == null
row[row.length - 2] = ''
row
stock = rows.reduce (prev, cur) ->
prev[prev.length - 1] = 'UK/DE'
if (prev[prev.length - 2])
prev[prev.length - 2] = prev[prev.length - 2] + '<br>' + cur[prev.length - 2]
else
prev[prev.length - 2] = cur[prev.length - 2]
prev
stock
rows
但不正确
注意:我不知道如何将下面的代码更改为 coffescript,所以我将在 javascript 中回答这个问题。
您可以执行以下操作:
- 使用 groupBy() 按
sku
对项目进行分组。 - map() the grouped items and return the transformed
qty
keys by country through reduce() and thetotal
value through sumBy().
var gb = [{"sku": "EP01", "qty": 10, "cntry": "GB"}, {"sku": "EP02", "qty": 5, "cntry": "GB"}, {"sku": "EP03", "qty": 15, "cntry": "GB"}];
var de = [{"sku": "EP01", "qty": 100, "cntry": "DE"}, {"sku": "EP02", "qty": 25, "cntry": "DE"}];
var result = _(gb)
.concat(de)
.groupBy('sku')
.map(function(items) {
return _.reduce(items, function(acc, item) {
return _(item)
.omit(['qty', 'cntry'])
.set('qty-' + item.cntry, item.qty)
.assign(acc)
.value();
}, { total: _.sumBy(items, 'qty') });
})
.value();
document.write('<pre>' + JSON.stringify(result, 0, 4) + '</pre>');
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.12.0/lodash.js"></script>
一个简单的解决方案 Javascript,其中一个对象作为对插入对象元素的引用。
var gb = [{ "sku": "EP01", "qty": 10, "cntry": "GB" }, { "sku": "EP02", "qty": 5, "cntry": "GB" }, { "sku": "EP03", "qty": 15, "cntry": "GB" }],
de = [{ "sku": "EP01", "qty": 100, "cntry": "DE" }, { "sku": "EP02", "qty": 25, "cntry": "DE" }],
result = function (data) {
function update(a) {
if (!hash[a.sku]) {
hash[a.sku] = { sku: a.sku, total: 0 };
r.push(hash[a.sku]);
}
hash[a.sku]['qty-' + a.cntry.toLowerCase()] = a.qty;
hash[a.sku].total += a.qty;
}
var hash = Object.create(null),
r = [];
data.forEach(a => a.forEach(update));
return r;
}([gb, de]);
document.write('<pre>' + JSON.stringify(result, 0, 4) + '</pre>');
因为你在 Node 上,所有 ES6 的好东西都可以为你服务。所以我不会使用额外的库,如 lodash 或下划线。你可以这样做
var gb = [{"sku": "EP01", "qty": 10, "cntry": "GB"}, {"sku": "EP02", "qty": 5, "cntry": "GB"}, {"sku": "EP03", "qty": 15, "cntry": "GB"}],
de = [{"sku": "EP01", "qty": 100, "cntry": "DE"}, {"sku": "EP02", "qty": 25, "cntry": "DE"}];
merged = (...arrs) => arrs.reduce((p,c) => c.reduce((f,s) => f.concat(s),p),[]);
document.write("<pre>" + JSON.stringify(merged(gb,de),null,2) + "</pre>");
如果您怀疑可能会出现任何重复,最好始终在链的末尾应用过滤器。我也会实现那个,仅供参考。