Javascript基于键合并两个对象

时间:2016-11-17 14:01:05

标签: javascript lodash

我有一些形状如下的物体。

[{
    product: 'ABC',
    productId: 'AB123',
    batch: 'BA1',
    price: '12'
}, {
    product: 'ABC',
    productId: 'AB123',
    batch: 'BA2',
    price: '15'
}, {
    product: 'XYZ',
    productId: 'AB124',
    batch: 'XY1',
    price: '124'
}]

如果要对密钥对(productproductId)进行算术,我希望将对象合并到数组中的单个对象中。

[{
    product: 'ABC',
    productId: 'AB123',
    batch: ['BA1', 'BA2'],
    price: ['12', '15']
}, {
    product: 'XYZ',
    productId: 'AB124',
    batch: 'XY1',
    price: '124'
}]

我如何在lodash或纯JavaScript中完成。

5 个答案:

答案 0 :(得分:3)

此提案不会改变给定的数据。

它创建新对象,首先只使用单个数据,稍后如果应该对更多数据进行分组,它会使用batchprice的数组。

var data = [{ product: 'ABC', productId: 'AB123', batch: 'BA1', price: '12' }, { product: 'ABC', productId: 'AB123', batch: 'BA2', price: '15' }, { product: 'XYZ', productId: 'AB124', batch: 'XY1', price: '124'}],
    merged = [];

data.forEach(function (a) {
    if (!this[a.productId]) {
        this[a.productId] =  { product: a.product, productId: a.productId, batch: a.batch, price: a.price };
        merged.push(this[a.productId]);
        return;
    }
    if (!Array.isArray(this[a.productId].batch)) {
        this[a.productId].batch = [this[a.productId].batch];
    }
    if (!Array.isArray(this[a.productId].price)) {
        this[a.productId].price = [this[a.productId].price];
    }
    this[a.productId].batch.push(a.batch);
    this[a.productId].price.push(a.price);
}, Object.create(null));

console.log(merged);

答案 1 :(得分:1)

您可以使用带有_.transform()_.mergeWith()的lodash链来合并数组中的类似对象:



$post->getCommentPage($comment)

function mergeSimilar(arr, arrayProps) {
  // transform the array into a map object
  return _(arr).transform(function(result, item) { 
    
    // create a temp id that includes the product and productId
    var id = item.product + item.productId; 
    
    // merge the existing item with a new item
    result[id] = _.mergeWith(result[id] || {}, item, function(objValue, srcValue, key) { 
      
      // if a value exists, and it's one of the request keys, concat them into a new array
      if (!_.isUndefined(objValue) && _.includes(arrayProps, key)) {
        return [].concat(objValue, srcValue);
      }
    });
  }, {})
  .values() // get the values from the map object
  .value();
}

var arr = [{
  product: 'ABC',
  productId: 'AB123',
  batch: 'BA1',
  price: '12'
}, {
  product: 'ABC',
  productId: 'AB123',
  batch: 'BA2',
  price: '15'
}, {
  product: 'XYZ',
  productId: 'AB124',
  batch: 'XY1',
  price: '124'
}];

var result = mergeSimilar(arr, ['batch', 'price']);

console.log(result);




答案 2 :(得分:1)

您可以使用_.uniqWith循环遍历集合并删除重复项。除此之外,uniqWith允许您访问对象本身,以便您可以随意篡改它们。

在这种情况下,当找到副本时,我将其批次和价格添加到原始对象的数组中,从而获得所需的结果。

array.append({"location": i["location"]})
var arr = [{
  product: 'ABC',
  productId: 'AB123',
  batch: 'BA1',
  price: '12'
}, {
  product: 'ABC',
  productId: 'AB123',
  batch: 'BA2',
  price: '15'
}, {
  product: 'XYZ',
  productId: 'AB124',
  batch: 'XY1',
  price: '124'
}];

function addToArray(val1, val2) {
  return _.isArray(val1) ? val1.concat(val2) : [val1].concat(val2);
}

function modifyObjs(a, b) {
  b.batch = addToArray(b.batch, a.batch);
  b.price = addToArray(b.price, a.price);
  return true;
}

function predicateAndModifier(a, b) {
  return a.product === b.product && a.productId === b.productId && modifyObjs(a, b);
}

console.log(_.uniqWith(arr, predicateAndModifier));

答案 3 :(得分:1)

Lodash 4.17.2

'201305'

答案 4 :(得分:0)

它必须是可读的吗?

var data = [{
    product: 'ABC',
    productId: 'AB123',
    batch: 'BA1',
    price: '12'
}, {
    product: 'ABC',
    productId: 'AB123',
    batch: 'BA2',
    price: '15'
}, {
    product: 'ABC',
    productId: 'AB113',
    batch: 'BA2',
    price: 15
}, {
    product: 'XYZ',
    productId: 'AB124',
    batch: 'XY1',
    price: '124'
}]
var unEs6 = function(x) {
    if (x instanceof Map) {
        var result = {}
        for (let [key, value] of x.entries()) {
            result[key] = unEs6(value);
        }
        return result;
    }
    else {
        return x
    }
}
JSON.stringify(unEs6(
    data
        .map(
            row => (new Map().set(
                row.product, new Map().set(
                    row.productId, new Map()
                        .set("batch", [row.batch])
                        .set("price", [row.price])
                    )
                )
            )
        )
        .reduce((a, b) => !a.has(b.keys().next().value) ?
            new Map([...a, ...b]) :
            !a.get(b.keys().next().value).has(b.get(b.keys().next().value).keys().next().value) ?
                a.set(b.keys().next().value, new Map([
                    ...a.get(b.keys().next().value),
                    ...b.get(b.keys().next().value)
                ])) :
                a.set(b.keys().next().value, a.get(b.keys().next().value).set(
                    b.get(b.keys().next().value).keys().next().value,
                    new Map()
                        .set("batch", a.get(b.keys().next().value).get(b.get(b.keys().next().value).keys().next().value).get("batch")
                              .concat(b.get(b.keys().next().value).get(b.get(b.keys().next().value).keys().next().value).get("batch"))
                        )
                        .set("price", a.get(b.keys().next().value).get(b.get(b.keys().next().value).keys().next().value).get("price")
                              .concat(b.get(b.keys().next().value).get(b.get(b.keys().next().value).keys().next().value).get("price"))
                        )
                ))
        )
))