获取JSON解析对象中的所有键/数组键?

时间:2019-07-02 14:10:57

标签: javascript angular lodash

我有这样的示例JSON

`{
  values:[{
    "name": "Base Url",
    "url": "https://kubemanagement-prod.kohls.com"
  },
  {
    "name": "Base Url newwww",
    "url": "https://batman.com"
  }]
}`

当前,当我将此特殊的JSON添加到lodash _.keys时,给我的结果["0", "1"]基本上是第一和第二个对象01的索引。

我真正想要的是检索JSON对象的所有键,包括子对象属性。在这种情况下,["values","0", "1","name","url"]

有人知道lodash方法或机制将复杂JSON对象中给定的所有键检索到第n级吗?

语言:角度+打字稿

4 个答案:

答案 0 :(得分:2)

此函数使用_.keys()_.flatMap()_.union()递归地从对象树中获取键,以组合键列表,并仅获取唯一值:

const getAllKeys = obj => _.union(
  _.keys(obj),
  _.flatMap(obj, o => _.isObject(o) ? getAllKeys(o) : [])
)

const arr = {"values": [{"name":"Base Url","url":"https://kubemanagement-prod.kohls.com"},{"name":"Base Url newwww","url":"https://batman.com"}]}

const result = getAllKeys(arr)

console.log(result)
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.js"></script>

同样的想法也没有lodash,使用Object.values()Array.flatMap()来迭代当前对象(或数组),并使用Array.concat()和Set来使键唯一:

const getAllKeys = obj => [...new Set([].concat(
  Object.keys(obj),
  Object.values(obj).flatMap(o => typeof o === 'object' ? getAllKeys(o) : [])
))]

const arr = {"values": [{"name":"Base Url","url":"https://kubemanagement-prod.kohls.com"},{"name":"Base Url newwww","url":"https://batman.com"}]}

const result = getAllKeys(arr)

console.log(result)
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.js"></script>

没有数组索引:

const getAllKeys = obj => _.union(
  _.isArray(obj) ? [] : _.keys(obj),
  _.flatMap(obj, o => _.isObject(o) ? getAllKeys(o) : [])
)

const arr = {"values": [{"name":"Base Url","url":"https://kubemanagement-prod.kohls.com"},{"name":"Base Url newwww","url":"https://batman.com"}]}

const result = getAllKeys(arr)

console.log(result)
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.js"></script>

答案 1 :(得分:1)

您不需要使用破折号,Object.keys就足够了。您只需编写一个递归函数,写入一个Set,或者在完成后转换为数组:

const array = [
  {
    "name": "Base Url",
    "url": "https://kubemanagement-prod.kohls.com"
  },
  {
    "name": "Base Url newwww",
    "url": "https://batman.com"
  }
];

function addAll(set, entries) {
    for (const entry of entries) {
        set.add(entry);
    }
    return set;
}

function allKeys(obj/*: object|array*/, keys/*: Set<string>*/ = new Set()) {
    addAll(keys, Object.keys(obj));
    for (const entry of Object.values(obj)) {
        if (entry && typeof entry === "object") {
            allKeys(entry, keys);
        }
    }
    return keys;
}

console.log([...allKeys(array)]);

或在编辑中使用结构:

const array = {
  values:[{
    "name": "Base Url",
    "url": "https://kubemanagement-prod.kohls.com"
  },
  {
    "name": "Base Url newwww",
    "url": "https://batman.com"
  }]
}

function addAll(set, entries) {
    for (const entry of entries) {
        set.add(entry);
    }
    return set;
}

function allKeys(obj/*: object|array*/, keys/*: Set<string>*/ = new Set()) {
    addAll(keys, Object.keys(obj));
    for (const entry of Object.values(obj)) {
        if (entry && typeof entry === "object") {
            allKeys(entry, keys);
        }
    }
    return keys;
}

console.log([...allKeys(array)]);

答案 2 :(得分:0)

怎么样

const arr = {"values": [{"name":"Base Url","url":"https://kubemanagement-prod.kohls.com"},{"name":"Base Url newwww","url":"https://batman.com"}]}

let result1 = Object.keys(arr) // get the object keys which is "values"
let result2 = Object.keys(arr[result1]); // get the keys of the object name "0,1" here
let result3 = Object.keys(arr[result1][0]); // get property names of one object "name and url" here
let resutltant = result1.concat(result2, result3) // "merge array"
console.log(resutltant)

假设您的对象属性名称将保持不变

答案 3 :(得分:-1)

如果您使用打字稿,为什么不使用Object.entries或Object.values来做到这一点?

您需要将tsconfig添加到下一行:

lib:[ ...... “ es2018”, ]