更改沿路径的嵌套对象

huangapple go评论73阅读模式
英文:

js / change nested object along path

问题

以下是代码部分的翻译,不包含问题和其他内容:

// 通过将路径存储在变量中来更改对象的内容
let path = ['props', 'children', 'props'];
children[path].children = 'test';

希望这对你有所帮助。

英文:

I have an object with a large nesting.
I can change its content like this:

children.props.children.props.children = 'test'

I can do this:

children['props']['children']['props'].children = 'test'

I want to do this by having the path in a variable

let path = ['props','children','props']

I tried like this:

let path = ['props','children','props']
children[path].children = 'test'

let path = [['props'],['children'],['props']]
children[path].children = 'test'

But it doesn't work. Please tell me how can I use the "path" variable

答案1

得分: 2

你可以尝试使用迭代方法“展开”对象:

const children = {
  props: {
    children: {
      props: {
        children: 'change me'
      }
    }
  }
};

const expandObject = (component, path) => {
  let ref = component;
  for (let i = 0; i < path.length; i++) {
    ref = ref[path[i]];
  }
  return ref;
};

let path = ['props', 'children', 'props'];

expandObject(children, path).children = 'test';

console.log(children);

这是一个使用深度的递归版本:

const children = {
  props: {
    children: {
      props: {
        children: {
          props: {
            children: 'change me'
          }
        }
      }
    }
  }
};

const deepAccess = (component, depth) =>
  (depth === 0)
    ? component
    : deepAccess(component.props.children, depth - 1);

const ref = deepAccess(children, 2);

ref.props.children = 'test';

console.log(children);

正如其他人所示,你可以减少路径:

const children = {
  props: {
    children: {
      props: {
        children: 'change me'
      }
    }
  }
};

const expandObject = (component, path) =>
  path.reduce((acc, path) => acc[path], component);

let path = ['props', 'children', 'props'];

expandObject(children, path).children = 'test';

console.log(children);
英文:

You can try to "expand" the object by using an iterative approach:

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-js -->

const children = {
  props: {
    children: {
      props: {
        children: &#39;change me&#39;
      }
    }
  }
};

const expandObject = (component, path) =&gt; {
  let ref = component;
  for (let i = 0; i &lt; path.length; i++) {
    ref = ref[path[i]];
  }
  return ref;
};

let path = [&#39;props&#39;, &#39;children&#39;, &#39;props&#39;];

expandObject(children, path).children = &#39;test&#39;;

console.log(children);

<!-- language: lang-css -->

.as-console-wrapper { top: 0; max-height: 100% !important; }

<!-- end snippet -->

Here is a recursive version that uses a depth:

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-js -->

const children = {
  props: {
    children: {
      props: {
        children: {
          props: {
            children: &#39;change me&#39;
          }
        }
      }
    }
  }
};

const deepAccess = (component, depth) =&gt;
  (depth === 0)
    ? component
    : deepAccess(component.props.children, depth - 1);

const ref = deepAccess(children, 2);

ref.props.children = &#39;test&#39;;

console.log(children);

<!-- language: lang-css -->

.as-console-wrapper { top: 0; max-height: 100% !important; }

<!-- end snippet -->

As others have shown, you can reduce the path:

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-js -->

const children = {
  props: {
    children: {
      props: {
        children: &#39;change me&#39;
      }
    }
  }
};

const expandObject = (component, path) =&gt;
  path.reduce((acc, path) =&gt; acc[path], component);

let path = [&#39;props&#39;, &#39;children&#39;, &#39;props&#39;];

expandObject(children, path).children = &#39;test&#39;;

console.log(children);

<!-- language: lang-css -->

.as-console-wrapper { top: 0; max-height: 100% !important; }

<!-- end snippet -->

答案2

得分: 1

这应该适用于你。

让路径 = ['props''children''props'];

const obj = { props{ children{ props{ childrennull } } } };

让上下文= obj;

对于路径中的每个名称请上下文=上下文[名称];
}

上下文.children=测试;

控制台.logobj
英文:

This should work for you.

let path = [&#39;props&#39;,&#39;children&#39;,&#39;props&#39;];

const obj = { props: { children: { props: { children: null } } } };

let context = obj;

for (const name of path) {
  context = context[name];
}

context.children = &quot;test&quot;;

console.log(obj)

答案3

得分: 0

这种方法会在路径上创建对象,如果它们尚不存在:

const obj = { a: { b: 'existing' } };

['a', 'c', 'd'].reduce((x, y) => x[y] ??= {}, obj).children = 'test';

console.log(obj)
英文:

This approach will create objects along the path if they don't already exist:

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-js -->

const obj = {a: { b: &#39;existing&#39; }};

[&#39;a&#39;,&#39;c&#39;,&#39;d&#39;].reduce((x,y)=&gt;x[y]??={},obj).children = &#39;test&#39;

console.log(obj)

<!-- end snippet -->

huangapple
  • 本文由 发表于 2023年3月10日 01:51:37
  • 转载请务必保留本文链接:https://go.coder-hub.com/75688327.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定