Hola tengo lo siguiente:

> 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' } ]
> 

Esto es incorrecto ya que obtengo dos { sku: 'EP01', qty: 100, cntry: 'DE' } donde me gustaría obtener un objeto combinado como { sku: 'EP01', total: 110, qty-gb: 10, qty-de: 100 }

Mi lista tiene alrededor de 8,000 entradas y, en algunos casos, una puede existir en una pero no en la otra.

¿Cuál es una manera eficiente de lograr esto en node.js con lodash?

Intenté esto:

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

Pero es incorrecta

0
khinester 10 may. 2016 a las 17:02

3 respuestas

La mejor respuesta

Nota: No sé cómo cambiar el siguiente código a coffreescript, así que solo responderé esto en javascript.

Puede hacer lo siguiente:

  1. Use groupBy () para agrupar elementos por sku.
  2. map () los elementos agrupados y devuelven las teclas qty transformadas por país a través de reduce () y el valor total a través de 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>
1
ryeballar 10 may. 2016 a las 14:23

Una solución en Javascript simple con un objeto como referencia a los elementos de los objetos insertados.

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>');
0
Nina Scholz 10 may. 2016 a las 14:52

Dado que está en el nodo, todas las ventajas de ES6 están a su servicio. Por lo tanto, no usaría bibliotecas adicionales como lodash o subrayado. Puedes hacer esto

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>");

En caso de que tenga dudas sobre la posibilidad de duplicados, siempre es mejor aplicar un filtro al final de la cadena. También implementaré ese fyi.

0
Redu 10 may. 2016 a las 14:33