用路径数组访问 JavaScript 元素

8

我得到了这个路径数组:

const path = ["a", "b", "c", "d"]

以及一个类似这样的对象:

let obj = { "a": { "b": { "c": { "d": 10, "e": 20 } } } }

我想要删除obj["a"]["b"]["c"]["d"],这样我的obj就会变成:

{ "a": { "b": { "c": { "e": 20 } } } }

我尝试使用path.forEach循环追加它,但是无法找到合适的方法来使我可以按照所需方式进行追加,并且能够将obj放置在正确的位置以便访问。

4个回答

19

您可以通过递归方式实现此操作,然后在基本情况下使用delete来删除最后一个键值对:

const path = ["a", "b", "c", "d"]
const obj = { "a": { "b": { "c": { "d": 10, "e": 20 } } } };

const remove_from_path = (obj, [prop, ...rest]) => 
  !rest.length ? delete obj[prop] : remove_from_path(obj[prop], rest);

remove_from_path(obj, path);
console.log(obj);


3
理解函数的第二个参数花了一些时间,我必须承认它非常巧妙。绝对有趣。 - briosheje
1
显然,选择复杂的代码比选择高效的代码更为重要。你和我代码的效率差别不到5%,因此可以忽略不计。我不明白的是为什么点赞数会有如此大的差异。 - nick zoum
2
@nickzoum 没有人这么说过。事实上,你的代码要快得多,但是使用for循环会更快。然而,这里提供的解决方案与for循环相比更短、更简洁、更易读。我不会说去编写复杂的代码更重要,相反,我们更倾向于编写易读、简短的代码——尽管这可能会更加复杂。 - Kobe
@Kobe,我觉得“理解函数的第二个参数花了一些时间”意味着它不太易读。 - nick zoum
2
如果你不熟悉语法,你就很可能对它的作用不熟悉。这句话可以用于任何事情。我经常使用解构赋值,所以对我来说很容易理解。我想这只是经验问题,但我发现在编写答案时效率会大打折扣。我已经开始写简短的答案,然后是高效的答案和一个 jsperf,我觉得这可能有助于新用户和那些寻找更快代码的人。 - Kobe
1
@nickzoum 我同意Kobe的观点,我们可以通过学习新的、不熟悉的知识来提高编程技能。因此我接受了这个答案。你的回答也很好,我也感谢你的回答。但对我来说,这个答案给了我一个很好的解构使用示例,一旦理解了解构,答案就不难了。 - jezrael

5

您可以遍历path数组,并在每次迭代中访问obj对象的该属性。在最后一次迭代中,不要输入最后一个属性,而是将其删除。

var path = ["a", "b", "c", "d"];
var obj = { "a": { "b": { "c": { "d": 10, "e": 20 } } } };

path.reduce(function(result, key, index) {
  if (index === path.length - 1) delete result[key];
  else return result[key];
}, obj);

console.log(obj);


5
你可以保存最后一个键并将对象减少到最终对象。

const
    remove = (object, [...keys]) => {
        const last = keys.pop();
        delete keys.reduce((o, k) => o[k] || {}, object)[last];
    },
    path = ["a", "b", "c", "d"],
    obj = { a: { b: { c: { d: 10, e: 20 } } } };


remove(obj, path);
console.log(obj);


0

let obj = { "a": { "b": { "c": { "d": 10, "e": 20 } } } };
const path = ["a", "b", "c", "d"];

const recursiveLookup = (obj) => {
  path.forEach((el) => {
    if(typeof obj[el] === 'object'){
      recursiveLookup(obj[el])
    } else {
      delete obj[el];
    }
  });
};
recursiveLookup(obj);

console.log(obj)


为什么要使用 typeof obj[el] === 'object'?如果 "d" 是一个对象该怎么办?如果它是 null 呢? - nick zoum
如果您将路径更改为 ["a", "b", "c"] 或 ["a", "b"],它就无法正常工作。 - Ghoul Ahmed
它只适用于这个特定的情况。如果“d”是null,那么它将失败。 - Nicolae Maties

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接