node - 从对象中获取更深层次的属性

node - get a deeper property out of object

提问人:Harald 提问时间:6/20/2023 更新时间:6/20/2023 访问量:40

问:

我有很多物品。这些对象具有不同的属性。为了检索所需的数据,我有它的路径。我的问题是:是否可以使用属性路径?

示例对象:

{ xy: 
  { item: [ 
            { z: { type: '1', id: 'myId', label: 'd', unit: 'dd', value: '11.20' }
          ] 
  } 
}

属性路径:

let path = "xy.item[0].z.value"

我尝试了以下操作(不起作用):

objectName[path]

它只对一个 propertyName 有效,但对“链”无效。有没有一个简单的解决方案可以从具有预定义路径的对象中获取所需的数据?

节点 .js 对象

评论

0赞 Wimanicesir 6/20/2023
为什么你必须“路径”它?你不能使用查找或过滤器来获得你想要的结果吗?
0赞 Marc 6/20/2023
这被称为“点符号”,并且存在使用它们的模块。

答:

1赞 MWY 6/20/2023 #1

我建议使用 Lodash。您可以使用 lodash 的 _.get() 函数从任何路径获取值。

const _ = require('lodash');

let objectName = { xy: { item: [ { z: { type: '1', id: 'myId', label: 'd', unit: 'dd', value: '11.20' } } ] } };
let path = "xy.item[0].z.value";

console.log(_.get(objectName, path));
1赞 gsck 6/20/2023 #2

您可以只实现一个解析字符串的函数,而不是包含一个全新的依赖项。

像这样的东西应该就足够了,它可能有点错误,因为我没有正确测试它,否则它应该是一个很好的起点,可以在不增加额外的 MB 的情况下实现你想要的。

let objectName = { xy: { item: [ { z: { type: '1', id: 'myId', label: 'd', unit: 'dd', value: '11.20' } } ] } };
let x = "xy.item[0].z.value";

function parsePath(toParse, obj) {
    const parts = toParse.split('.');

    let current = obj;

    for (let i = 0; i < parts.length; i++) {
        const currentPart = parts[i];
        const indecies = currentPart.split('[')
        for (let j = 0; j < indecies.length; j++) {
            let currentIndex = indecies[j];
            if (currentIndex.endsWith(']')) {
                currentIndex = Number.parseFloat(currentIndex.replace(']', ''))
            }
            current = current[currentIndex]
        }
    }

    return current
}

parsePath(x, objectName) // Returns '11.20' as expected

上面的代码不支持字符串索引(即 xy[“item”]),但这应该很难实现。

1赞 Rode093 6/20/2023 #3

首先,json obj 无效。您缺少一个右大括号。

在这里,我构建了一个函数,该函数可以根据您在字符串中定义的路径从嵌套对象返回值。该函数可以处理具有数组和子数组的嵌套对象。例如,路径类似于“xy.item[0][0].z.value”

const obj = {
  xy: {
    item: [
      {
        z: { type: "1", id: "myId", label: "d", unit: "dd", value: "11.20" },
      },
    ],
  },
};

let path = "xy.item[0].z.value";

function findNestedValue(obj, path) {
  path_nodes = path.split(".");

  let val = obj; // value is set to the whole object value in the beginging
  for (let node of path_nodes) {
    let array_indexes = node.match(RegExp(/\[(\w)*\]/g));
    if (array_indexes) {
      //  trying to access array
      // get the array
      let key = node.slice(0, node.indexOf("["));
      val = val[key]; // now value is the array
      for (let index of array_indexes) {
        val = val[index.slice(1, index.length - 1)];
      }
    } else {
      //it is trying to access property
      val = val[node];
    }
  }
  return val;
}

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

评论

1赞 Harald 6/20/2023
效果完美。谢谢!
0赞 Rode093 6/21/2023
很棒的:)不客气。