合并JavaScript对象 [英] Merging javascript objects

查看:74
本文介绍了合并JavaScript对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

希望合并两个对象.但是,当两个对象中都存在具有相同值的属性"date"时,其他属性(tag1和tag2)将在同一日期合并.

Wish to merge two objects. However, when a property "date" with same value exists in both the objects, the other properties (tag1 and tag2) are to be clubbed under the same date.

示例输入

var myVar1 = [
{
"date": "2015-07-16",
  "tag1": 35.34},
{
"date": "2015-07-18",
  "tag1": 34.12}
  ];

var myVar2 = [
{
"date": "2015-07-16",
  "tag2": 45.34},
{
"date": "2015-07-17",
  "tag2": 44.12}
  ];

所需的输出

mergedVar = [
{
"date": "2015-07-16",
  "tag1": 35.34,
  "tag2": 45.34},
{
"date": "2015-07-17",
  "tag2": 44.12},
{
"date": "2015-07-18",
  "tag1": 34.12}
  ];

推荐答案

我发表我的评论的想法是,其他人会发表更严肃的答案,但是由于没人来,我想我会描述你可能会如何认真做.

I posted my comment with the idea that someone else would post a more serious answer, but since nobody came along, I guess I’ll describe how you might go about doing it seriously.

首先,您必须知道如何将一个对象合并到另一个对象中.不太困难,但是您必须知道如何使用for-in,这是不常讲授的,通常最好包括一个hasOwnProperty支票,这种支票的使用频率要低一些:

First, you’ll have to know how to merge one object into another. It’s not too difficult, but you do have to know how to use for-in, which isn’t frequently taught, and it’s usually a good idea to include a hasOwnProperty check which is even less-frequently taught:

function mergeObjectInto(source, target) {
    for(var property in source) {
        if(Object.prototype.hasOwnProperty.call(source, property)) {
            target[property] = source[property];
        }
    }
}

从本质上讲,这枚举了源的所有属性.如果该属性是对象的 own 属性(也就是说,它不是从其原型继承的东西),则将该属性复制到目标.

Essentially, this enumerates over all properties of the source. If that property is an own property of the object—that is, it’s not something it inherited from its prototype—we copy that property over to the target.

现在,要对您要执行的操作进行建模,我们可以将其分解为更简单的操作:给定一个现有数组,将另一个对象放入该数组,并在必要时合并.天真的实现可能看起来像这样:

Now, to model the kind of operation you want to do, we can decompose it down into a simpler operation: given an existing array, put another object in that array, merging if necessary. A naïve implementation might look like this:

function mergeObjectIntoArray(existingArray, newObject) {
    // Search for an already-existing object in the array that shares the same
    // value for the `date' property.
    var correspondingExistingObject = null;
    for(var index = 0, length = existingArray.length; index < length; index++) {
        if(existingArray[index].date === newObject.date) {
            correspondingExistingObject = existingArray[index];
            break;
        }
    }
    if(correspondingExistingObject !== null) {
        // If we found an existing object that corresponds to our new object, just
        // merge any new properties in rather than adding a new item to the array.
        mergeObjectInto(newObject, correspondingExistingObject);
    }else{
        // Otherwise, bite the bullet and add the new object since there's nothing
        // we can usefully merge into.
        existingArray.push(newObject);
    }
}

然后,您可以通过循环调用此函数来实现所需的合并操作.但是,如果计算出来的话,那将是二次时间,如果必须处理大量的数据项,这将是一个问题.碰巧的是,有一种方法可以解决它.如果我们将项目分类为一个以date属性为键的类似于哈希表的结构,则可以在固定时间内检查是否有一个带有该日期的对象,如果有,请合并到该对象中;否则,请执行以下操作:否则,添加它.这导致整个算法的线性时间非常合理.

You could then implement the sort of merge operation you wanted by calling this function in a loop. But if you work it out, that’s going to have quadratic time, which will be an issue if this has to work on a large number of data items. As it happens, there is a way you can work around it. If we sort items into a hash-table-like structure keyed by date property as we go, we can check in constant time whether we have an object with that date or not, and if so, merge into it; otherwise, add it. That leads to a very reasonable linear time for the entire algorithm.

一个复杂的问题是,直到最近使用ECMAScript 6,JavaScript才真正拥有真正的哈希表".我们拥有的最接近的东西是对象,只能有字符串键.这将对我们有用,但我们需要谨慎行事:无论好坏,浏览器供应商都创建了一些具有特殊意义的属性名称,例如__proto__,我们确实不想继续使用,所以我们会在我们的键之前添加一些字符,以防止与内置名称发生任何冲突.为此,我选择了#. (#是一个哈希,它是一个哈希表.)

One complication is that until recently with ECMAScript 6, JavaScript hasn’t really had a real "hash table". The closest thing we have are objects, which can only have string keys. That’ll work for us, but we do need to exercise some caution: for better or worse, browser vendors have created some property names with special significance, like __proto__, that we really don’t want to step on, so we’ll prefix our keys with some character that prevents any clashes with built-in names. I chose # for this purpose. (# is a hash, and it’s a hash-table.)

在代码中,这是如何实现的,这一次该函数接收整个项目数组并将所有具有重复的date属性值的对象合并:

In code, here’s how that would work out, this time the function taking an entire array of items and merging all objects with duplicate date property values:

function mergeDuplicateObjectsInArray(array) {
    var result = [];
    var objectsByDate = {};
    for(var index = 0, length = array.length; index < length; index++) {
        var object = array[index];
        var hashKey = '#' + object.date;
        var mergeTarget;
        if(Object.prototype.hasOwnProperty.call(objectsByDate, hashKey)) {
            // Already have an object by that date; we ought to merge into that.
            mergeObjectInto(object, objectsByDate[object.date]);
        }else{
            // No object by that date yet; we'll be the first.
            result.push(object);
            objectsByDate[object.date] = object;
        }
    }
    return result;
}

这仍然遗漏了最后一件事:它只是将对象合并在一个数组中,而不是两个不同的数组.但是,如果您使用两个数组的对象创建单个数组,它将达到您想要的效果,例如myVar1.concat(myVar2).无论如何,您还可以修改其中的for循环以遍历数组数组,然后遍历那些数组中的对象,这是我的高尔夫版本所做的.高尔夫版本的另一个区别是高尔夫版本避免修改原始数组或对象,这是对未混淆版本的相对简单的修改:要进行复制,只需合并到一个空对象中即可.

This still misses out on one last thing: it’s only merging objects within a single array, not two different arrays. But it will do what you want if you created a single array with the objects of both arrays, e.g. myVar1.concat(myVar2). In any case, you could also modify the for loop in it to loop over an array of arrays, and then loop over the objects in those arrays, which is what my golfed version did. The other difference to the golfed version is the golfed version avoids modifying the original arrays or objects, which would be a relatively simple modification of the unobfuscated version: to make a copy, just merge into an empty object.

希望这可以清除一切.

这篇关于合并JavaScript对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆