给定2个对象,创建第三个对象,其中包含来自对象1和2的值以及KEEP原始顺序

时间:2018-06-12 13:55:01

标签: javascript jquery

它应该快速而简单但不是:(

我有2个对象数组,如下所示:

var obj1 = {
 1: "Available"
 3: "Available - Sleeps"
}
var obj2 = {
 2: "Not Available"
 4: "Holidays"
 6: "Sick"
}

我想有一个第三个对象,它是两个保持原始顺序的合并,如下所示:

var obj3 = {
 1: "Available"
 3: "Available - Sleeps"
 2: "Not Available"
 4: "Holidays"
 6: "Sick"
}

不幸的是,它总是按键排序,所以我得到了这个:(:

var obj3 = {
 1: "Available"
 2: "Not Available"
 3: "Available - Sleeps"
 4: "Holidays"
 6: "Sick"
}

我尝试过不同的方法来合并对象,但顺序永远不会保持不变,我试过了:

$.extend(obj3, obj1, obj2);
obj3 = Object.assign(obj1, obj2);
obj3 = {...obj1,...obj2}

任何人的想法:)

由于

4 个答案:

答案 0 :(得分:0)

对象属性枚举顺序不可靠。

使用Map代替,因为它会保留广告订单:

const map1 = new Map([
  [1, "Available"],
  [3, "Available - Sleeps"]
])

const map2 = new Map([
  [2, "Not Available"],
  [4, "Holidays"],
  [6, "Sick"]
])

const map3 = new Map([...map1, ...map2])

console.log([...map3])

// Also you can easily convert and object to dictionary:
const fromPairs = pairs => {
  const obj = {}

  for (let [key, value] of pairs)
    obj[key] = value

  return obj
}

const obj = fromPairs(map3)

console.log(obj)

请参阅此其他问答以获取有关对象属性枚举顺序的更多见解:Does JavaScript Guarantee Object Property Order?

答案 1 :(得分:0)

您无法使用这些属性键创建一个对象,该对象的属性将按照您所说的顺序进行枚举。从ES2015开始,对象属性 do 有一个顺序(官方仅为某些操作指定,但所有现代JavaScript引擎也将其应用于未指定的操作)。该顺序的一个方面是,在数字顺序中访问由规范*定义的名称为整数索引的属性。您的123等属性符合整数索引键的定义,因此合并对象的属性将枚举为1,2,3,...顺序

相反,请使用数组:

const obj3 = [];
Object.keys(obj1).forEach(key => { obj3.push({key, value: obj1[key]}); });
Object.keys(obj2).forEach(key => { obj3.push({key, value: obj2[key]}); });

var obj1 = {
 1: "Available",
 3: "Available - Sleeps"
};
var obj2 = {
 2: "Not Available",
 4: "Holidays",
 6: "Sick"
};
const obj3 = [];
Object.keys(obj1).forEach(key => { obj3.push({key, value: obj1[key]}); });
Object.keys(obj2).forEach(key => { obj3.push({key, value: obj2[key]}); });
console.log(obj3);
.as-console-wrapper {
  max-height: 100% !important;
}

...虽然从技术上讲,如果您将这些名称设为而不是整数索引,您可以创建一个具有按该顺序计算的属性的对象:

var obj3 = {};
Object.keys(obj1).forEach(key => { obj3["x" + key] = obj1[key]; });
Object.keys(obj2).forEach(key => { obj3["x" + key] = obj2[key]; });

var obj1 = {
 1: "Available",
 3: "Available - Sleeps"
};
var obj2 = {
 2: "Not Available",
 4: "Holidays",
 6: "Sick"
};
var obj3 = {};
Object.keys(obj1).forEach(key => { obj3["x" + key] = obj1[key]; });
Object.keys(obj2).forEach(key => { obj3["x" + key] = obj2[key]; });
console.log(obj3);

但是我不推荐

*定义here

  

整数索引是一个字符串值属性键,它是一个规范数字字符串(见7.1.16),其数值为+0或正整数≤2 53功能 -1。

答案 2 :(得分:0)

也许这很有帮助。



var obj1 = {
 1: "Available",
 3: "Available - Sleeps"
}
var obj2 = {
 2: "Not Available",
 4: "Holidays",
 6: "Sick"
}

const merged = Object.values(obj1).concat(Object.values(obj2)).reduce((result, value, index)=>{result[index] = value; return result},{})

console.log(merged)




答案 3 :(得分:0)

如果你真的想保留按键的顺序,那么如果我是你,我就会这样做:



var obj1 = {
 1: "Available",
 3: "Available - Sleeps"
};
var obj2 = {
 2: "Not Available",
 4: "Holidays",
 6: "Sick"
}

Object.defineProperty(Object.prototype, 'orderedKeys', {
  get: function () {
    return this.hasOwnProperty('orderedKeys') ? this.orderedKeys : Object.keys(this);
  }, 
  enumerable: false
});

Object.defineProperty(Object.prototype, 'concat', {
  value: function (obj) {
    return {
      ...this, 
      ...obj,
      orderedKeys: this.orderedKeys.concat(Object.keys(obj))
    };
  }, 
  enumerable: false
});

var obj3 = obj1.concat(obj2);
console.log(obj3);
for(const key of obj3.orderedKeys) {
  console.log(key, obj3[key]);
}




这样,您始终可以在orderedKeys中保留按键的有序版本,以便日后使用。