Javascript:使用动态变量名称访问 JSON 数据中的嵌套值

发布于 2024-10-07 09:20:16 字数 1031 浏览 3 评论 0原文

我有一个像 Here 这样的嵌套 Javascript 对象

var data = { 'name':    { 'heading': 'Name', 'required': 1, 'type': 'String' },
             'profile': {
                  'age':   { 'heading': 'Age', 'required': 0, 'type': 'Number' },
                  'phone': { 'heading': 'Phone', 'required': 0, 'type': 'String'},
                  'city':  { 'heading': 'City', 'required': 0, 'type': 'String'},
                  },
             'status':  { 'heading': 'Status', 'required': 1, 'type': 'String' }
           };

,我可以通过 data.profile.age.type 或 data.name.type 访问字段。没有问题 如果我有动态变量名称,我可以按如下方式访问。再说一遍,没问题。

f = 'profile'; data[f].age.type

但是,这里我有诸如“name”、“profile.age”、“profile.city”等变量名称,显然我无法将它们作为 f = 'profile.age'; 访问它们。 data[f].type 不起作用。

谁能指导我如何以最直接和简单的方式访问它们(获取/设置)?

注意:我尝试过这个,它适用于 get。

data.get = function(p) { o = this; return eval('o.'+p); };
f = 'profile.age'; data.get(f).name;

虽然设置似乎不够简单。如果对于获取和设置还有更好的解决方案,请告诉我。

I have a nested Javascript object like

var data = { 'name':    { 'heading': 'Name', 'required': 1, 'type': 'String' },
             'profile': {
                  'age':   { 'heading': 'Age', 'required': 0, 'type': 'Number' },
                  'phone': { 'heading': 'Phone', 'required': 0, 'type': 'String'},
                  'city':  { 'heading': 'City', 'required': 0, 'type': 'String'},
                  },
             'status':  { 'heading': 'Status', 'required': 1, 'type': 'String' }
           };

Here, I can access the fields as data.profile.age.type or data.name.type. No Issues
And if I have dynamic variable names, I can access as below. Again, No Problems.

f = 'profile'; data[f].age.type

But, here I have variable names like 'name', 'profile.age', 'profile.city' etc and obviously I cannot access them as f = 'profile.age'; data[f].type which will not work.

Can anyone guide me how to access them (get/set) in the most straight-forward and simple way?

Note: I tried this and it works for get.

data.get = function(p) { o = this; return eval('o.'+p); };
f = 'profile.age'; data.get(f).name;

though set does not seem to be simple enough. Please let me know, if there are better solutions for get and set as well.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

谢绝鈎搭 2024-10-14 09:20:16

除非绝对必要,否则不要使用eval。 :) 至少在这种情况下,有更好的方法来做到这一点 - 您可以将嵌套名称拆分为各个部分并迭代它们:

data.get = function(p) {
  var obj = this;

  p = p.split('.');
  for (var i = 0, len = p.length; i < len - 1; i++)
    obj = obj[p[i]];

  return obj[p[len - 1]];
};

data.set = function(p, value) {
  var obj = this;

  p = p.split('.');
  for (var i = 0, len = p.length; i < len - 1; i++)
    obj = obj[p[i]];

  obj[p[len - 1]] = value;
};

Don't use eval unless absolutely necessary. :) At least in this case, there are better ways to do it -- you can split the nested name into individual parts and iterate over them:

data.get = function(p) {
  var obj = this;

  p = p.split('.');
  for (var i = 0, len = p.length; i < len - 1; i++)
    obj = obj[p[i]];

  return obj[p[len - 1]];
};

data.set = function(p, value) {
  var obj = this;

  p = p.split('.');
  for (var i = 0, len = p.length; i < len - 1; i++)
    obj = obj[p[i]];

  obj[p[len - 1]] = value;
};
╭⌒浅淡时光〆 2024-10-14 09:20:16

您可以只嵌套括号:

var a = 'name', b = 'heading';
data[a][b]; // = `Name`

You can just nest the brackets:

var a = 'name', b = 'heading';
data[a][b]; // = `Name`
英雄似剑 2024-10-14 09:20:16

也许是一个函数,它接受您感兴趣的属性的路径并将其分解为表示属性的标记。像这样的东西(当然,这很粗糙):

data.get = function(path) {
  var tokens = path.split('.'), val = this[tokens[0]];
  if (tokens.length < 2) return val;
  for(var i = 1; i < tokens.length; i++) {
     val = val[tokens[i]];
  }
  return val;
}

例如:

   var f = 'one.two';
   var data = { one: {two:'hello'}};
   data.get = /* same as above */;

   var val = data.get(f);

Perhaps a function that takes in the path to the property you're interested in and breaks it up into tokens representing properties. Something like this (this is very rough, of course):

data.get = function(path) {
  var tokens = path.split('.'), val = this[tokens[0]];
  if (tokens.length < 2) return val;
  for(var i = 1; i < tokens.length; i++) {
     val = val[tokens[i]];
  }
  return val;
}

example:

   var f = 'one.two';
   var data = { one: {two:'hello'}};
   data.get = /* same as above */;

   var val = data.get(f);
╰◇生如夏花灿烂 2024-10-14 09:20:16

访问/设置嵌套值的一种简洁方法是在 ES6 中使用 reduce

const x = ['a', 'b', 'c'], o = {a: {b: {c: 'tigerking'}}}

// Get value: "tigerking"
console.log(x.reduce((a, b) => a[b], o)) 

// Set value: 
x.slice(0, x.length-1).reduce((a, b) => a[b], o)[x[x.length-1]] = 'blossom'

console.log(o) // {a: {b: {c: 'blossom'}}}

因此,您可以首先使用 'profile.age'.split('.') 将变量 'profile.age' 转换为数组,然后使用上面的方法。

A clean way to access/set nested values is using reduce in ES6:

const x = ['a', 'b', 'c'], o = {a: {b: {c: 'tigerking'}}}

// Get value: "tigerking"
console.log(x.reduce((a, b) => a[b], o)) 

// Set value: 
x.slice(0, x.length-1).reduce((a, b) => a[b], o)[x[x.length-1]] = 'blossom'

console.log(o) // {a: {b: {c: 'blossom'}}}

So, you can first convert your variable 'profile.age' to an array using 'profile.age'.split('.'), then use the approach above.

冷情妓 2024-10-14 09:20:16

这使用 jquery.each() 函数使用可能包含也可能不包含一个或多个“.”的字符串变量来遍历 json 树。您也可以传入一个数组并省略 .split();

pathString = 类似“person.name”的内容

jsonObj = 类似 {"person" : {"name":"valerie"}} 的内容。

function getGrandchild(jsonObj, pathString){
    var pathArray = pathString.split(".");
    var grandchild = jsonObj;
    $.each(pathArray, function(i, item){
        grandchild = grandchild[item];
    });
    return grandchild;
};

返回“瓦莱丽”

This uses the jquery.each() function to traverse down a json tree using a string variable that may or may not contain one or more "."'s. You could alternatively pass in an array and omit the .split();

pathString = something like "person.name"

jsonObj = something like {"person" : {"name":"valerie"}}.

function getGrandchild(jsonObj, pathString){
    var pathArray = pathString.split(".");
    var grandchild = jsonObj;
    $.each(pathArray, function(i, item){
        grandchild = grandchild[item];
    });
    return grandchild;
};

returns "valerie"

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文