javascript 如何在每个子集对象中创建一个名为“name”的新属性,并将父对象的键名作为其值?

yks3o0rb  于 12个月前  发布在  Java
关注(0)|答案(6)|浏览(93)

我知道这个标题可能有点让人困惑,所以我会试着用视觉来解释。我已经挣扎了好几天了,我到处都找过了,但这是一个非常具体的任务。
我收到了这个API响应:

{
  akash: {
    url: "127.0.0.1",
    count: 12
  },
  aptos: {
    url: "127.0.0.2",
    count: 54
  }
}

字符串
我需要将它转换为一个新的对象,格式如下:

{
  akash: {
    name: "akash",
    url: "127.0.0.1",
    count: 12
  },
  aptos: {
    name: "aptos",
    url: "127.0.0.2",
    count: 54
  }
}


如果你知道的话,现在每个子集都有一个新的属性“name”,它的值是父对象的键名。
另一种方法是将其转换为适当的对象数组,如下所示:

[{
  name: "akash",
  url: "127.0.0.1",
  count: 12
}, {
  name: "aptos",
  url: "127.0.0.2",
  count: 54
}]

wh6knrhe

wh6knrhe1#

您可以在对象的关键点之间切换。
如果你有一个originalObject作为起点,你可以使用以下代码创建一个新对象:

const newObject = {};
for (const key in originalObject) {
    const value = { ...originalObject[key], name: key };
    newObject[key] = value;
}

字符串
要创建列表,过程非常相似,但您要生成一个新的对象数组并将新值推送到列表中:

const newList = [];
for (const key in originalObject) {
    const value = { ...originalObject[key], name: key };
    newList.push(value);
}

oogrdqng

oogrdqng2#

https://tsplay.dev/WPB8ZN

type AddName<O, P = never> = {
  [K in keyof O | (P extends never ? never : 'name')]: K extends keyof O ?
  O[K] extends object ? AddName<O[K], K> : O[K]
  : P
} & unknown

function addName<O extends object, S>(o: O, name?: S): AddName<O, unknown extends S ? never : S> {
  if (name !== undefined) Object.assign(o, {name})
  for (let [k, v] of Object.entries(o)) {
    if (typeof o === 'object'&& o !== null) {
      addName(v, k)
    }
  }
  return o as any;
}

字符串
这确实是递归的(注意,这会将name添加到现有对象,而不是创建新对象)

8xiog9wr

8xiog9wr3#

当使用JSON时,对象可以在使用JSON.parse()的reviver参数进行格式化时直接修改。

function reviver(key, value) {
  const isObject = typeof value === "object" && value !== null && !Array.isArray(value);
  const isInsideArray = Array.isArray(this);
  
  if (key !== "" && isObject && !isInsideArray) {
    value.name = key;
  }
  
  return value;
}

const json = `{
   "akash": {
      "url": "127.0.0.1",
      "count": 12
   },
   "aptos": {
      "url": "127.0.0.2",
      "count": 54
   }
}`;

const obj = JSON.parse(json, reviver);

console.log(obj);

个字符
此reviver将name属性分配给任何对象,使其与包含它的键相同。它跳过对数组或其中包含的项目进行此操作,以避免添加名称作为索引:

function reviver(key, value) {
  const isObject = typeof value === "object" && value !== null && !Array.isArray(value);
  const isInsideArray = Array.isArray(this);
  
  if (key !== "" && isObject && !isInsideArray) {
    value.name = key;
  }
  
  return value;
}

const json = `{
   "akash": {
      "url": "127.0.0.1",
      "count": 12
   },
   "aptos": {
      "url": "127.0.0.2",
      "count": 54
   },
   "array": [{"foo": 1}, {"foo": 2}, {"foo": 3}]
}`;

const obj = JSON.parse(json, reviver);

console.log(obj);
.as-console-wrapper { max-height: 100% !important; }

的字符串
如果应该给数组中的对象添加一个名称,那么这个例子展示了如何做到这一点。这里所有对象都将获得保存数组值的键:

function reviver(key, value) {
  const isObject = typeof value === "object" && value !== null;
  const isInsideArray = Array.isArray(this);
  
  if (key !== "" && isObject && !isInsideArray) {
    if (Array.isArray(value))
      return value.map(x => reviver(key, x, true));
    else 
      value.name = key;
  }
  
  return value;
}

const json = `{
   "akash": {
      "url": "127.0.0.1",
      "count": 12
   },
   "aptos": {
      "url": "127.0.0.2",
      "count": 54
   },
   "array": [{"foo": 1}, {"foo": 2}, {"foo": 3}]
}`;

const obj = JSON.parse(json, reviver);

console.log(obj);
.as-console-wrapper { max-height: 100% !important; }
67up9zun

67up9zun4#

因为OP想要改变基于对象的数据的数据结构,所以主任务总是必须遍历对象的所有条目,而不管最终的基本数据结构是数组还是对象。
Object.entries这样的方法提供了一个包含所有对象条目的数组。
在数组作为目标数据结构的情况下,只需要map每个条目,它是一个key及其相关value的数组/元组。然后可以通过对象字面量和扩展语法生成条目特定的新对象。
如果一个对象作为目标数据结构,我们可以通过将一个空对象(例如一个空的对象字面量)作为初始值传递给reduce方法的第二个参数,将entries-array再次reduce到一个对象中。最终结果然后通过Object.assign在每次迭代中逐步聚合,其中我们确实将新创建的条目特定对象合并到当前对象中。

const sampleData = {
  akash: {
    url: "127.0.0.1",
    count: 12
  },
  aptos: {
    url: "127.0.0.2",
    count: 54
  }
};

const arrayOfMappedDataEntries = Object
  .entries(sampleData)
  .map(([name, data]) => ({ name, ...data }));

const alteredObjectStructure = Object
  .entries(sampleData)
  .reduce((result, [name, data]) =>
    Object.assign(result, { [ name ]: { name, ...data } }), {}
  );

console.log({
  sampleData,
  alteredObjectStructure,
  arrayOfMappedDataEntries,
});

个字符

  • 编辑**.
  • “Ah yet another take at reduce,with Object.assign this time..
const sampleData = {
  akash: {
    url: "127.0.0.1",
    count: 12
  },
  aptos: {
    url: "127.0.0.2",
    count: 54
  }
};

const alteredObjectStructure = Object
  .fromEntries(
    Object
      .entries(sampleData)
      .map(([name, data]) => [name, { name, ...data }])
  );

console.log({
  sampleData,
  alteredObjectStructure,
});
.as-console-wrapper { min-height: 100%!important; top: 0; }

的字符串

2hh7jdfx

2hh7jdfx5#

首先回答

let obj={
  akash: {
    url: "127.0.0.1",
    count: 12
  },
  aptos: {
    url: "127.0.0.2",
    count: 54
  }
}

for(let key in obj){
  obj={...obj,[key]:{...obj[key],name:key}}
     }

字符串

第二个答案

let obj1={
  akash: {
    url: "127.0.0.1",
    count: 12
  },
  aptos: {
    url: "127.0.0.2",
    count: 54
  }
}
let result = []

for(let key in obj1){
  // {optus:{},akash:{}}
  let temp={...obj1[key],name:key}
  result= [...result,temp ]
}
console.log(result)

u0njafvf

u0njafvf6#

我是一个JavaScript的初学者。如果让我来写这些代码,我想我会这样写

const source = {
   "akash": {
      "url": "127.0.0.1",
      "count": 12
   },
   "aptos": {
      "url": "127.0.0.2",
      "count": 54
   }
};

const result = {...source}

for (const key in source) {
 result[key].name = key;
}

字符串

相关问题