簡體   English   中英

合並兩個 javascript 對象,添加公共屬性的值

[英]Merge two javascript objects adding values of common properties

我有兩個或多個 javascript 對象。 我想合並它們添加公共屬性的值,然后按值的降序對它們進行排序。

例如

var a = {en : 5,fr: 3,in: 9}
var b = {en: 8,fr: 21,br: 8}

var c = merge(a,b)

c應該是這樣的:

c = {
fr: 24,
en: 13,
in:9,
br:8
} 

即合並兩個對象,添加公共鍵的值,然后對鍵進行排序。

這是我嘗試過的:

var a = {en : 5,fr: 3,in: 9}
var b = {en: 8,fr: 21,br: 8}
c = {}

// copy common values and all values of a to c
for(var k in a){
  if(typeof b[k] != 'undefined'){  
    c[k] = a[k] + b[k]  
  }
  else{ c[k] = a[k]}
}

// copy remaining values of b (which were not common)
for(var k in b){
 if(typeof c[k]== 'undefined'){
  c[k] = b[k]
 }
} 

// Create a object array for sorting
var arr = [];

for(var k in c){
 arr.push({lang:k,count:c[k]})
}

// Sort object array
arr.sort(function(a, b) {
   return b.count - a.count;
})

但我不認為它好。 這么多循環:(如果有人能提供一個不那么混亂和好的代碼,那就太好了。

在 ES2015+ 中,對象屬性有序的(首先是數字鍵的升序,然后是非數字鍵的插入順序)。 如果您使用指定迭代順序的方法之一(例如Object.getOwnPropertyNames ),則規范可以保證這一點。

在 ES2020+ 中,以前未指定枚舉順序的方法現在已指定(盡管環境已經遵循它多年了)。

但是您必須確保沒有任何屬性是數字的(否則,無論插入順序如何,它們都會先出現在非數字屬性之前)。

使用reduce迭代每個對象並在累加器上創建或添加相同的屬性。 然后, sort對象的條目進行sort ,並使用Object.fromEntries將其轉換為具有排序屬性的對象。 不需要 jQuery:

 var a = {en : 5,fr: 3,in: 9} var b = {en: 8,fr: 21,br: 8} console.log(merge(a, b)); function merge(...objects) { const merged = objects.reduce((a, obj) => { Object.entries(obj).forEach(([key, val]) => { a[key] = (a[key] || 0) + val; }); return a; }, {}); return Object.fromEntries( Object.entries(merged).sort( (a, b) => b[1] - a[1] ) ); }

無法對對象的屬性進行排序,但是您可以對數組進行排序:

var merged = $.extend({}, a);
for (var prop in b) {
    if (merged[prop]) merged[prop] += b[prop];
    else merged[prop] = b[prop];
}
// Returning merged at this point will give you a merged object with properties summed, but not ordered.
var properties = [];
for (var prop in merged) {
    properties.push({
        name: prop,
        value: merged[prop]
    });
}
return properties.sort(function(nvp1, nvp2) {
    return nvp1.value - nvp2.value;
});

編輯 - 我修改了腳本,如果屬性屬於相同類型,則合並屬性:數字相加,字符串連接,對象遞歸合並。 我沒有包括排序,因為(引用這個答案Sorting JavaScript Object by property value

JavaScript 對象根據定義是無序的(參見 ECMAScript 語言規范,第 8.6 節)。 語言規范甚至不能保證,如果您連續兩次迭代對象的屬性,它們第二次將以相同的順序出現。

如果您需要訂購東西,請使用數組和 Array.prototype.sort 方法。

function is_object(mixed_var) {
    if (Object.prototype.toString.call(mixed_var) === '[object Array]') {
        return false;
    }
    return mixed_var !== null && typeof mixed_var == 'object';
}

function merge(a, b) {
    var cache = {};
    cache = unpackObject(a, cache);
    cache = unpackObject(b, cache);
    return cache;


}

function unpackObject(a, cache) {
    for (prop in a) {
        if (a.hasOwnProperty(prop)) {
            if (cache[prop] === undefined) {
                cache[prop] = a[prop];
            } else {
                if (typeof cache[prop] === typeof a[prop]) {
                    if (is_object(a[prop])) {
                        cache[prop] = merge(cache[prop], a[prop]);
                    } else {
                        cache[prop] += a[prop];
                    }
                }
            }
        }
    }
    return cache;
}

var a = {
    en: 5,
    fr: 3,
    in : 9,
    lang: "js",
    object: {nestedProp: 6}

}
var b = {
    en: 8,
    fr: 21,
    br: 8,
    lang: "en",
    object: {nestedProp: 1, unique: "myne"}
}

var c = merge(a, b);

在這里小提琴http://jsfiddle.net/vyFN8/1/

這是我的嘗試,它對嵌套對象是遞歸的 - https://gist.github.com/greenafrican/19bbed3d8baceb0a15fd

// Requires jQuery
// Merge nested objects and if the properties are numbers then add them together, else
// fallback to jQuery.extend() result

function mergeObjectsAdd(firstObject, secondObject) {
    var result = $.extend(true, {}, firstObject, secondObject);
    for (var k in result) {
        if ("object" === typeof result[k]) {
            firstObject[k] = firstObject[k] || {};
            secondObject[k] = secondObject[k] || {};
            result[k] = mergeObjectsAdd(firstObject[k], secondObject[k]);
        } else {
            firstObject[k] = firstObject[k] || 0;
            secondObject[k] = secondObject[k] || 0;
            result[k] = ("number" === typeof firstObject[k] && "number" === typeof secondObject[k]) ? (firstObject[k] + secondObject[k]) : result[k];
        }
    }
    return result;
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM