【问题标题】:Can I pass in variables as keys in pouchdb upsert我可以在 pouchdb upsert 中将变量作为键传递吗
【发布时间】:2021-06-24 08:49:00
【问题描述】:

我想在使用 pouchdb 的插件 upsert 时传入用户定义的变量。理想情况下,是这样的:

var res = db.upsert(uniqueID, (doc) => {
 doc.data.var1.var2.var3 = userInput
}

我的尝试:

var res = db.upsert(uniqueID, (doc) => {
 doc.data = {[var1]:
                {[var2]:
                  {[var3]: userInput}
                 }
             }
}

这会导致doc.data 的内容被每个新变量重复覆盖。

现在,有没有办法简单地定义一个嵌套的、依赖于变量的键,我打算更新插入?

每个var3: userInput 的文件似乎都太过分了。

【问题讨论】:

  • 使用变量键对doc.data 的赋值有效,所以缺少一些东西。请澄清“被每个新变量重复覆盖”的意思。
  • 使用= 右侧的变量效果很好。我想要做的是像doc.data.var1.var2 = var3 这样在左侧传递它们。实际上,doc.data 应该有多个数组,随着时间的推移由多个变量定义。上面的最后一个示例始终返回 doc.data 作为最新的 upsert,并覆盖了任何其他(如预期的那样)。
  • 您说“多个数组”,但我根本看不到数组,只是嵌套对象。通常,您是否需要一种在某些键路径之后添加嵌套值的方法,例如键 = [var1,var2,var3], 值 = someValue ?

标签: javascript arrays database pouchdb upsert


【解决方案1】:

Javascript 中不存在“如果键不存在,则使其值成为对象”行为。例如如果doc = {} 那么

doc.data.foo.bar = "fail"

总是会失败,因为 data 未定义。

可以定义一个简单的函数来提供这样的功能。

function setDeepValue(target, keyPath, value) {
  const key = keyPath.shift();
  if (key !== undefined) {
    // there is more work to be done.
    if (keyPath.length === 0) {
      // we're at the end of the path, assign key to value
      target[key] = value;
    } else {
      if (target[key] === undefined) {
        // create an object for the key
        target[key] = {};
      }
      // keep going.
      setDeepValue(target[key], keyPath, value);
    }
  }
}
//
// demo the function
//
const doc = {};
let var1 = "key1",
  var2 = "key2",
  var3 = "key3";
const keyPath = ["data", var1, var2, var3];
const value = "My Value";
console.log("doc before:\n" + JSON.stringify(doc, undefined, 3));
setDeepValue(doc, keyPath, value);
console.log("doc after:\n" + JSON.stringify(doc, undefined, 3));

我不认为上面的代码是最佳的,但它确实可以完成工作。

【讨论】:

  • 太棒了!这完美无缺。非常感谢您的时间和精力。
  • 尝试使用 newDoc = {...oldDoc, ...newArray} 对其进行优化,但它遭受与 upsert 相同的命运。也许几年后,当 JS 发展起来的时候,我们都会回过头来笑一笑。
  • 确实 newDoc = {...obj1,...jb2} 有效,但仅适用于 ES2018。使用 ES2015 Object.assign(obj1, obj2) 也可以。但是,这两种情况都不适用于您的情况,因为您的偏好是回避显式对象创建,如帖子的“我尝试过的内容”部分所述。很高兴能帮上忙。回复:stackoverflow.com/questions/171251/…
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-05-15
  • 2021-10-15
  • 2012-06-28
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多