如何使用 lodash 或不使用 lodash 通过特定值从嵌套 JSON 创建键数组?
How to create key array from nested JSON by particular value with lodash or without lodash?
我想创建值为“str”的键数组
我有以下嵌套 json:
[
{
"Attr": [
{
"power": { "p1": "str", "t3": "str" },
"light": [
{"test": "str"},
{"test2": [ { "t4": "str" }]}
]
}
]
},
{
"Attr1": [
{
"power1": { "p2": "str", "t5": "str" },
"light1": [
{ "test3": "str" },
{ "test_x": [
{ "t_x": "str" },
{ "t_y": [
{ "t_y1": "str" }
]
}
]
}
]
}
]
}
]
我想创建键值为“str”的键数组,
我想要得到以下数组输出:
["p1", "t3", "test", "p2", "t5", "test3", "t_x", "t_y1"]
如何根据特定值从嵌套 JSON 创建键数组?
尝试这样的事情:
var array = [];
function searchForStringInJsonRecursive (jsonData, str) {
for(var i in jsonData) {
// If the element is an Array or nested object continue to search
if (typeof jsonData[i] === 'object') {
searchForStringInJsonRecursive(jsonData[i], str);
}
// If the element is not an Object and matches str add the it to the array
else if (jsonData[i] === str) {
array.push(i);
}
}
}
假设您的 json 在一个名为 data
的变量中,您可以这样调用该函数:
searchForStringInJsonRecursive(data, 'str');
array
将包含内容匹配 'str'
的所有键
如果你能写出一个性能最好的递归函数。
但是如果你想跳过递归调用(对于嵌套对象中的每个键),那么你可以尝试 JSON.parse
带有附加参数(回调),它将被它递归调用。作为通用解决方案,我添加了一个片段(JSON.parse
,假设帮助编写递归函数不应该被接受/这个答案的一部分)。
但请记住,如果您担心性能效率,则不应使用它,因为您必须进行字符串化(可能是一个大对象)并再次解析。但是,如果你有一个 JSON 字符串,它应该是最好的解决方案之一。
var anyObject = [
{
"Attr": [
{
"power": { "p1": "str", "t3": "str" },
"light": [
{"test": "str"},
{"test2": [ { "t4": "str" }]}
]
}
]
},
{
"Attr1": [
{
"power1": { "p2": "str", "t5": "str" },
"light1": [
{ "test3": "str" },
{ "test_x": [
{ "t_x": "str" },
{ "t_y": [
{ "t_y1": "str" }
]
}
]
}
]
}
]
}
]
function getKeys(obj, str) {
let resultArr = [];
JSON.parse(JSON.stringify(obj), (key, val) => {
if(val === str) { resultArr.push(key) }
return val;
} )
return resultArr;
}
console.log(getKeys(anyObject, 'str'))
这不是特定情况,如果你在 JSON.parse
中传递另一个回调,你可以拥有所有的键,也可以使用它转换对象(返回转换后的值而不是实际值)
而如果你想使用lodash递归迭代对象,那么你可以使用
_.cloneDeepWith
用于递归迭代对象。
这是一个工作示例:
let anyObject = [
{
"Attr": [
{
"power": { "p1": "str", "t3": "str" },
"light": [
{"test": "str"},
{"test2": [ { "t4": "str" }]}
]
}
]
},
{
"Attr1": [
{
"power1": { "p2": "str", "t5": "str" },
"light1": [
{ "test3": "str" },
{ "test_x": [
{ "t_x": "str" },
{ "t_y": [
{ "t_y1": "str" }
]
}
]
}
]
}
]
}
];
function getKeys(obj, str) {
let resultArr = [];
_.cloneDeepWith(obj, (value, key) => { value === 'str' && resultArr.push(key)});
return resultArr;
}
console.log(getKeys(anyObject, 'str'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.10/lodash.min.js"></script>
恕我直言,您可能正在寻找这样的东西:
var testArr = [{"Attr":[{"power":{"p1":"str","t3":"str"},"light":[{"test":"str"},{"test2":[{"t4":"str"}]}]}]},{"Attr1":[{"power1":{"p2":"str","t5":"str"},"light1":[{"test3":"str"},{"test_x":[{"t_x":"str"},{"t_y":[{"t_y1":"str"}]}]}]}]}];
var strFind = (arr, accumulator = []) => {
arr.forEach(obj => {
Object.entries(obj).forEach(([key, value]) => {
if (value === "str") accumulator.push(key);
if (Array.isArray(value)) strFind(value, accumulator);
if (key.includes("power")) {
Object.entries(value).forEach(([cKey, cValue]) => {
if (cValue === "str") accumulator.push(cKey);
})
}
});
})
return accumulator;
}
console.log(strFind(testArr));
另一个尝试使用 JSON.stringify
和字符串解析:
const result = JSON.stringify(data)
.match(/"[^"]+":"str"/g) // get all "xxx":"str" pairs
.map(r => r.substring(1, r.indexOf(':') - 1)); // pick out all "xxx"
console.log(result);
// ["p1", "t3", "test", "t4", "p2", "t5", "test3", "t_x", "t_y1"]
这是使用 lodash
的一种方法:
var testArr = [{"Attr":[{"power":{"p1":"str","t3":"str"},"light":[{"test":"str"},{"test2":[{"t4":"str"}]}]}]},{"Attr1":[{"power1":{"p2":"str","t5":"str"},"light1":[{"test3":"str"},{"test_x":[{"t_x":"str"},{"t_y":[{"t_y1":"str"}]}]}]}]}];
var findStr = function(o) {
return _(o)
.map(function(v, k) {
return v === 'str'
? k
: _.isObject(v) ? findStr(v) : null;
})
.compact()
.flatten()
.value();
};
console.log(findStr(testArr));
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.10/lodash.min.js"></script>
还有另一种可能性,利用 JSON.stringify
的自然递归性质:
const input = [{"Attr":[{"power":{"p1":"str","t3":"str"},"light":[{"test":"str"},{"test2":[{"t4":"str"}]}]}]},{"Attr1":[{"power1":{"p2":"str","t5":"str"},"light1":[{"test3":"str"},{"test_x":[{"t_x":"str"},{"t_y":[{"t_y1":"str"}]}]}]}]}];
const output = [];
JSON.stringify(input, (key, val) => {
if (val === 'str') output.push(key);
return val;
});
console.log(output);
我做过……我用过lodash
。我的代码如下:
var arrayData = [];
var teatData = [
{
"Attr": [
{
"power": { "p1": "str", "t3": "str" },
"light": [
{"test": "str"},
{"test2": [ { "t4": "str" }]}
]
}
]
},
{
"Attr1": [
{
"power1": { "p2": "str", "t5": "str" },
"light1": [
{ "test3": "str" },
{ "test_x": [
{ "t_x": "str" },
{ "t_y": [
{ "t_y1": "str" }
]
}
]
}
]
}
]
}
];
function getKeyArray(data, arrayData) {
if (Array.isArray(data)) {
_.forEach(data, (obj, key) => {
this.getKeyArray(obj, arrayData);
});
} else if (_.isPlainObject(data)) {
_.forEach(data, (obj, key) => {
if (obj === "str") {
arrayData.push(key);
} else if (Array.isArray(obj) || _.isPlainObject(obj)) {
this.getKeyArray(obj, arrayData);
}
});
}
}
getKeyArray(teatData, arrayData);
console.log(arrayData);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.10/lodash.js"></script>
我想创建值为“str”的键数组 我有以下嵌套 json:
[
{
"Attr": [
{
"power": { "p1": "str", "t3": "str" },
"light": [
{"test": "str"},
{"test2": [ { "t4": "str" }]}
]
}
]
},
{
"Attr1": [
{
"power1": { "p2": "str", "t5": "str" },
"light1": [
{ "test3": "str" },
{ "test_x": [
{ "t_x": "str" },
{ "t_y": [
{ "t_y1": "str" }
]
}
]
}
]
}
]
}
]
我想创建键值为“str”的键数组,
我想要得到以下数组输出:
["p1", "t3", "test", "p2", "t5", "test3", "t_x", "t_y1"]
如何根据特定值从嵌套 JSON 创建键数组?
尝试这样的事情:
var array = [];
function searchForStringInJsonRecursive (jsonData, str) {
for(var i in jsonData) {
// If the element is an Array or nested object continue to search
if (typeof jsonData[i] === 'object') {
searchForStringInJsonRecursive(jsonData[i], str);
}
// If the element is not an Object and matches str add the it to the array
else if (jsonData[i] === str) {
array.push(i);
}
}
}
假设您的 json 在一个名为 data
的变量中,您可以这样调用该函数:
searchForStringInJsonRecursive(data, 'str');
array
将包含内容匹配 'str'
如果你能写出一个性能最好的递归函数。
但是如果你想跳过递归调用(对于嵌套对象中的每个键),那么你可以尝试 JSON.parse
带有附加参数(回调),它将被它递归调用。作为通用解决方案,我添加了一个片段(JSON.parse
,假设帮助编写递归函数不应该被接受/这个答案的一部分)。
但请记住,如果您担心性能效率,则不应使用它,因为您必须进行字符串化(可能是一个大对象)并再次解析。但是,如果你有一个 JSON 字符串,它应该是最好的解决方案之一。
var anyObject = [
{
"Attr": [
{
"power": { "p1": "str", "t3": "str" },
"light": [
{"test": "str"},
{"test2": [ { "t4": "str" }]}
]
}
]
},
{
"Attr1": [
{
"power1": { "p2": "str", "t5": "str" },
"light1": [
{ "test3": "str" },
{ "test_x": [
{ "t_x": "str" },
{ "t_y": [
{ "t_y1": "str" }
]
}
]
}
]
}
]
}
]
function getKeys(obj, str) {
let resultArr = [];
JSON.parse(JSON.stringify(obj), (key, val) => {
if(val === str) { resultArr.push(key) }
return val;
} )
return resultArr;
}
console.log(getKeys(anyObject, 'str'))
这不是特定情况,如果你在 JSON.parse
中传递另一个回调,你可以拥有所有的键,也可以使用它转换对象(返回转换后的值而不是实际值)
而如果你想使用lodash递归迭代对象,那么你可以使用
_.cloneDeepWith
用于递归迭代对象。
这是一个工作示例:
let anyObject = [
{
"Attr": [
{
"power": { "p1": "str", "t3": "str" },
"light": [
{"test": "str"},
{"test2": [ { "t4": "str" }]}
]
}
]
},
{
"Attr1": [
{
"power1": { "p2": "str", "t5": "str" },
"light1": [
{ "test3": "str" },
{ "test_x": [
{ "t_x": "str" },
{ "t_y": [
{ "t_y1": "str" }
]
}
]
}
]
}
]
}
];
function getKeys(obj, str) {
let resultArr = [];
_.cloneDeepWith(obj, (value, key) => { value === 'str' && resultArr.push(key)});
return resultArr;
}
console.log(getKeys(anyObject, 'str'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.10/lodash.min.js"></script>
恕我直言,您可能正在寻找这样的东西:
var testArr = [{"Attr":[{"power":{"p1":"str","t3":"str"},"light":[{"test":"str"},{"test2":[{"t4":"str"}]}]}]},{"Attr1":[{"power1":{"p2":"str","t5":"str"},"light1":[{"test3":"str"},{"test_x":[{"t_x":"str"},{"t_y":[{"t_y1":"str"}]}]}]}]}];
var strFind = (arr, accumulator = []) => {
arr.forEach(obj => {
Object.entries(obj).forEach(([key, value]) => {
if (value === "str") accumulator.push(key);
if (Array.isArray(value)) strFind(value, accumulator);
if (key.includes("power")) {
Object.entries(value).forEach(([cKey, cValue]) => {
if (cValue === "str") accumulator.push(cKey);
})
}
});
})
return accumulator;
}
console.log(strFind(testArr));
另一个尝试使用 JSON.stringify
和字符串解析:
const result = JSON.stringify(data)
.match(/"[^"]+":"str"/g) // get all "xxx":"str" pairs
.map(r => r.substring(1, r.indexOf(':') - 1)); // pick out all "xxx"
console.log(result);
// ["p1", "t3", "test", "t4", "p2", "t5", "test3", "t_x", "t_y1"]
这是使用 lodash
的一种方法:
var testArr = [{"Attr":[{"power":{"p1":"str","t3":"str"},"light":[{"test":"str"},{"test2":[{"t4":"str"}]}]}]},{"Attr1":[{"power1":{"p2":"str","t5":"str"},"light1":[{"test3":"str"},{"test_x":[{"t_x":"str"},{"t_y":[{"t_y1":"str"}]}]}]}]}];
var findStr = function(o) {
return _(o)
.map(function(v, k) {
return v === 'str'
? k
: _.isObject(v) ? findStr(v) : null;
})
.compact()
.flatten()
.value();
};
console.log(findStr(testArr));
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.10/lodash.min.js"></script>
还有另一种可能性,利用 JSON.stringify
的自然递归性质:
const input = [{"Attr":[{"power":{"p1":"str","t3":"str"},"light":[{"test":"str"},{"test2":[{"t4":"str"}]}]}]},{"Attr1":[{"power1":{"p2":"str","t5":"str"},"light1":[{"test3":"str"},{"test_x":[{"t_x":"str"},{"t_y":[{"t_y1":"str"}]}]}]}]}];
const output = [];
JSON.stringify(input, (key, val) => {
if (val === 'str') output.push(key);
return val;
});
console.log(output);
我做过……我用过lodash
。我的代码如下:
var arrayData = [];
var teatData = [
{
"Attr": [
{
"power": { "p1": "str", "t3": "str" },
"light": [
{"test": "str"},
{"test2": [ { "t4": "str" }]}
]
}
]
},
{
"Attr1": [
{
"power1": { "p2": "str", "t5": "str" },
"light1": [
{ "test3": "str" },
{ "test_x": [
{ "t_x": "str" },
{ "t_y": [
{ "t_y1": "str" }
]
}
]
}
]
}
]
}
];
function getKeyArray(data, arrayData) {
if (Array.isArray(data)) {
_.forEach(data, (obj, key) => {
this.getKeyArray(obj, arrayData);
});
} else if (_.isPlainObject(data)) {
_.forEach(data, (obj, key) => {
if (obj === "str") {
arrayData.push(key);
} else if (Array.isArray(obj) || _.isPlainObject(obj)) {
this.getKeyArray(obj, arrayData);
}
});
}
}
getKeyArray(teatData, arrayData);
console.log(arrayData);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.10/lodash.js"></script>