javascript 将一个对象的关键帧应用到具有不同值但结构相同的另一个对象上

i34xakig  于 2023-01-29  发布在  Java
关注(0)|答案(3)|浏览(100)

给定以下两个对象:

const obj1 = {
   value1: 'Hello',
   value2: 'Goodbye',
   value3: ['yes', 'no'],
   value4: {
      value5: 'Phone'
   }
}

const obj2 = {
   v1: 'Orange',
   v2: 'Apple',
   v3: ['Cat', 'Dog'],
   v4: {
      v5: 'Basketball'
   }
}

假设键/值的结构/数量相同,我如何将第一个对象的键应用到第二个对象上?返回:

{
   value1: 'Orange',
   value2: 'Apple',
   value3: ['Cat', 'Dog'],
   value4: {
      value5: 'Basketball'
   }
}

任何帮助将不胜感激!

q8l4jmvw

q8l4jmvw1#

const obj1 = {"value1":"Hello","value2":"Goodbye","value3":["yes","no"],"value4":{"value5":"Phone"}}
const obj2 = {"v1":"Orange","v2":"Apple","v3":["Cat","Dog"],"v4":{"v5":"Basketball"}}

const values = (a,b,c) => (c = Object.values(b), Object.entries(a).map(([k,v],i)=>[k,v,c[i]]))
const f = (a,b) => (values(a,b).forEach(([k,v,v2])=>v instanceof Object ? f(v,v2) : a[k]=v2), a)
console.log(f(structuredClone(obj1), obj2))
noj0wjuj

noj0wjuj2#

从您的问题陈述来看,您似乎想要修改obj2的键,而不需要obj1。
你可以用递归的简单方法来实现:

function updateKeys(obj) {
   for (let key in obj) {
     const newKey = `value${key.slice(1)}`
     obj[newKey] = obj[key]
     delete obj[key]
     
     if (typeof obj[newKey] === 'object' && !Array.isArray(obj[newKey])) {
       updateKeys(obj[newKey])
     }
   }
}
updateKeys(obj2)
oyjwcjzk

oyjwcjzk3#

我建议你重新考虑一下,我们可以写这样一个函数,安德鲁·帕克斯的答案是一种,下面是另一种:

const copyStruct = (x, y, xs = Object .entries (x), ys = Object .values (y)) => 
  Object .assign (
    Array .isArray (x) ? [] : {}, 
    ... xs .map (([k, v], i) => ({[k]: Object (v) === v ? copyStruct (v, ys[i]) : ys[i]}))
  )

const obj1 = {"value1":"Hello","value2":"Goodbye","value3":["yes","no"],"value4":{"value5":"Phone"}}
const obj2 = {"v1":"Orange","v2":"Apple","v3":["Cat","Dog"],"v4":{"v5":"Basketball"}}

console .log (copyStruct (obj1, obj2))
    • 但是**,这是非常脆弱的。最好的方式来考虑对象是作为 * 无序 * 的键-值对的集合。这里你依赖于一个非常脆弱的方式排序。

例如,这确实应该是一个no-op:

const temp = obj1 .value1
delete obj1 .value1
obj1 .value1 = temp

obj1的键值与定义时相同,但是现在如果你运行Andrew的代码或者我的代码,你的结果会是这样的:

{
  value2: "Orange",
  value3: ["A", "p"],
  value4: {value5: "Cat"},
  value1: {v5: "Basketball"}
}

或者再举一个例子,当键看起来像小整数时,我们甚至不修改对象,我们的迭代顺序就不同了:

const obj1 = {"3": "Hello",     "1":"Goodbye", "2":"Phone",      "4": "yes"}
const obj2 = {"5": "Orange",    "6":"Apple",   "4":"Basketball", "7": "cat"}

将导致:

{"1":"Basketball", "2":"Orange",  "3":"Apple",      "4":"cat"}

有可能从这些混乱中恢复过来,我确信您的示例只是虚拟的示例数据,但是如果您实际上在两个对象中的键之间有直接的关系,例如

const newKey = key .replace ('value', 'v')

那么我们可以写一个非常简单的递归函数来解决你的问题。否则,我建议重新考虑你的方法。

相关问题