【问题标题】:How to add key value pair in array of Mongoose response in JavaScript如何在 JavaScript 中的 Mongoose 响应数组中添加键值对
【发布时间】:2022-04-16 01:15:10
【问题描述】:

我尝试做一些基本的事情。我有一个包含多个对象的数组。我想在每个数组对象中添加新的键值对。

我通过以下代码进行了尝试。

exports.addBuyOption = (arr) => {
    var newArr=arr;
    return new Promise((resolve, reject) => {
        for (let i = 0; i < newArr.length; i++) {
            newArr[i].name="new name" //updating the existing key value
            newArr[i].canBuy=true //new key value 
        }

        setTimeout(() => {
            resolve(newArr);
        }, 2000)
    })
}

我添加了设置超时,因为我只是想确认在循环操作之后是否返回了 Promise。此外,当代码不与原始数组一起运行时,我会使用 newArr 名称创建一个新变量,但代码也不起作用。

exports.addBuyOption = (arr) => {
    return new Promise((resolve, reject) => {
        for (let i = 0; i < arr.length; i++) {
            arr[i].name="new name" //updating the existing key value
            arr[i].canBuy=true //new key value 
        }

            resolve(arr);
    })
}

使用此代码,我能够更新现有的键值,但无法添加任何新的键值。我究竟做错了什么?我试图改变将键从点运算符添加到数组索引到 Object.assign 的方法,但它们都不适合我。

【问题讨论】:

  • 为什么超时和承诺?这不仅仅是直接的对象操作吗?也请使用[&lt;&gt;] sn-p 编辑器发布minimal reproducible example
  • 如果更新现有属性有效,该代码肯定会将新属性添加到对象中,除非那些非常不寻常的对象已应用preventExtensions(在这种情况下,您可以't 添加新属性)。请使用 minimal reproducible example 来更新您的问题,以展示问题,最好是使用 Stack Snippets([&lt;&gt;] 工具栏按钮)的 runnable 问题; here's how to do one.
  • 旁注:newArr 是该变量的误导性名称。它不是一个新数组,它只是另一个指向同一个数组arr 的变量。该变量没有理由,您可能只是使用arr。如果您确实想要制作数组的副本,则必须故意这样做,如果您想要制作数组 in 对象的副本,则必须这样做也是。
  • 另外,你的问题与html无关。
  • “我添加了设置超时,因为我只是想确认在循环操作之后是否返回了承诺。” 没有超时,该承诺就没有任何意义。

标签: javascript mongodb mongoose


【解决方案1】:

使用此代码,我能够更新现有的键值,但无法添加任何新的键值。

对此的唯一解释是数组中的对象已应用Object.preventExtensions。这是一个例子:

function addBuyOption(arr) {
    for (let i = 0; i < arr.length; i++) {
        arr[i].name="new name" //updating the existing key value
        arr[i].canBuy=true //new key value 
    }
    return arr;
}

const arr = [
    {name: "old name 1"},
    {name: "old name 2"},
    {name: "old name 3"},
].map(Object.preventExtensions);
console.log("Before:");
console.log(JSON.stringify(arr, null, 4));
addBuyOption(arr);
console.log("After:");
console.log(JSON.stringify(arr, null, 4));
.as-console-wrapper {
    max-height: 100% !important;
}

(注意我取消了这个承诺,它在这段代码中没有做任何有用的事情。)

如果发生这种情况,您将无法向对象添加属性。但是您可以使用新属性创建一个包含对象副本的新数组:

function addBuyOption(arr) {
    return arr.map(obj => ({
        ...obj,           // Copy existing properties
        name: "new name", // Set new value for existing property
        canBuy: true,     // Set new property
    }));
}

const arr = [
    {id: 1, name: "old name 1"},
    {id: 2, name: "old name 2"},
    {id: 3, name: "old name 3"},
].map(Object.preventExtensions);
console.log("Before:");
console.log(JSON.stringify(arr, null, 4));
const newArr = addBuyOption(arr);
console.log("After:");
console.log(JSON.stringify(newArr, null, 4));
.as-console-wrapper {
    max-height: 100% !important;
}

【讨论】:

  • 谢谢。我检查了更多答案,并通过在数组上使用 JSON stringify 和 parse 方法,我能够在数组中添加一个新的键值。代码没问题,实际上是mongoose限制了数组更新(不知道为什么)。
  • @Pranaykumar - "...通过在数组上使用 JSON 字符串化和解析方法,我能够在数组中添加一个新的键值..." 你会看到有人这样做,但我强烈建议:不要。 JSON.parse(JSON.stringify(x)) 有损且速度慢,这是一种糟糕的复制方式。没有理由通过文本进行往返。相反,请执行我上面显示的操作(对于您所描述的内容,您只需要浅拷贝),或者 do this 在极少数情况下需要深拷贝。编码愉快!
猜你喜欢
  • 2013-09-28
  • 1970-01-01
  • 2015-08-11
  • 2014-07-09
  • 2015-11-10
  • 1970-01-01
  • 2022-08-18
  • 2017-05-27
  • 1970-01-01
相关资源
最近更新 更多