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

zpf6vheq  于 2023-06-22  发布在  Node.js
关注(0)|答案(3)|浏览(154)

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

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

属性路径:

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

我试过以下方法(不起作用):

objectName[path]

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

zte4gxcn

zte4gxcn1#

首先,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));
qxsslcnc

qxsslcnc2#

我建议使用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));
tsm1rwdh

tsm1rwdh3#

您可以只实现一个解析字符串的函数,而不是包含一个全新的依赖项。
像这样的东西应该足够了,它可能有点bug,因为我还没有正确地测试它,否则它应该是一个很好的起点,以实现你想要的,而不添加额外的几个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”]),但这应该很难实现。

相关问题