我遇到了一个问题,我希望使用现有的数组,并使用for循环更新它的一个属性.我希望外部id和数组内的id匹配,例如:a&a、b&b、c&c.然而,当我打印出最后一个数组时,所有内部id都设置为c.

我不明白为什么会发生这种事?

编辑:添加了预期yields

My Code

  const accounts = [{ 
      "id": 1,
      "currency": "USD"
  }];

  const alphaId = ['a', 'b', 'c'];
  
  let finalArr = []; 

  for (index in alphaId) {
  
    let newAccount = {};
    newAccount.id = alphaId[index];
  
    newAccount.accounts = accounts;
    newAccount.accounts.forEach(acc => {
      acc.id = alphaId[index];
    });

    finalArr.push(newAccount);
  }

Print Out

[
  {
    "id": "a",
    "accounts": [
      {
        "id": "c",
        "currency": "USD"
      }
    ]
  },
  {
    "id": "b",
    "accounts": [
      {
        "id": "c",
        "currency": "USD"
      }
    ]
  },
  {
    "id": "c",
    "accounts": [
      {
        "id": "c",
        "currency": "USD"
      }
    ]
  }
]

Expected Output

[
  {
    "id": "a",
    "accounts": [
      {
        "id": "a",
        "currency": "USD"
      }
    ]
  },
  {
    "id": "b",
    "accounts": [
      {
        "id": "b",
        "currency": "USD"
      }
    ]
  },
  {
    "id": "c",
    "accounts": [
      {
        "id": "c",
        "currency": "USD"
      }
    ]
  }
]

推荐答案

问题就在这里:

newAccount.accounts = accounts;

这只是使新对象上的属性accountssame array引用为accounts,而不复制array.因此,您的所有代码都在同一数组上工作,并且在该数组中的同一对象上工作.

我怀疑你的意思是同时复制数组和其中的对象.我们可以用map来做这件事,让它返回新的对象.

newAccount.accounts = accounts.map((account) => ({...account}));

它使用mapspread syntax(it's not an operator)arrow functions.它使用了简洁的箭头函数形式(箭头后面没有{),其中主体只是一个表达式.因为我们返回的是以{开头的Object文本,所以我们必须将整个正文包装在()中,这样解析器才能意识到我们使用的是简明形式.如果我们使用"Verbose"形式,它将如下所示:

newAccount.accounts = accounts.map((account) => {
    return {...account};
});

以下是最小的更新版本,但请继续阅读:

const accounts = [
    {
        id: 1,
        currency: "USD",
    },
];

const alphaId = ["a", "b", "c"];

let finalArr = [];

for (index in alphaId) {
    let newAccount = {};
    newAccount.id = alphaId[index];

    newAccount.accounts = accounts.map((account) => ({...account}));
    newAccount.accounts.forEach((acc) => {
        acc.id = alphaId[index];
    });

    finalArr.push(newAccount);
}

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

它在accounts中循环两次:一次是复制,另一次是赋值id.我们可以只做一次,在复制时分配id,使用map:

newAccount.accounts = accounts.map((account) => ({...account, id: alphaId[index]}));

const accounts = [
    {
        id: 1,
        currency: "USD",
    },
];

const alphaId = ["a", "b", "c"];

let finalArr = [];

for (index in alphaId) {
    let newAccount = {};
    newAccount.id = alphaId[index];

    newAccount.accounts = accounts.map((account) => ({...account, id: alphaId[index]}));

    finalArr.push(newAccount);
}

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


其他一些注意事项:

  1. for-in不是循环数组的正确方式(通常),有关各种选项的详细信息,请参阅my answer here.

  2. 因为finalArralphaId的ID值到对象的映射,所以我们可以使用map来代替循环,在map中处理创建新帐户:

示例:

const finalArr = alphaId.map((id) => ({
    id,
    accounts: accounts.map((account) => ({...account, id})),
}));

const accounts = [
    {
        id: 1,
        currency: "USD",
    },
];

const alphaId = ["a", "b", "c"];

const finalArr = alphaId.map((id) => ({
    id,
    accounts: accounts.map((account) => ({...account, id})),
}));

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

Javascript相关问答推荐

如何使用Echart 5.5.0创建箱形图

Exceljs:我们在file.xlsx(...)&#中发现了一个问题'"" 39人;

将现场录音发送到后端

我们如何从一个行动中分派行动

你怎么看啦啦队的回应?

还原器未正确更新状态

当输入字段无效时,我的应用程序不会返回错误

如何在Node.js中排除导出的JS文件

Rxjs流中生成IMMER不能在对象上操作

Puppeteer上每页的useProxy返回的不是函数/构造函数

将异步回调转换为异步生成器模式

以编程方式聚焦的链接将被聚焦,但样式不适用

Docent.cloneNode(TRUE)不克隆用户输入

使用Reaction窗体挂钩注册日历组件

Cherrio JS返回父div的所有图像SRC

使用静态函数保存 node 前的钩子

如何从Reaction-Redux中来自API调用的数据中筛选值

Playwright:ReferenceError:browserContext未定义

Js问题:有没有办法将数据从标记表转换成图表?

如何将.jsx转换为.tsx