如何通过使用lodash或不使用lodashi的特定值从嵌套的JSON创建键数组



我想要创建值为">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中创建键数组?

IMHO,您可能正在寻找这样的东西:

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.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递归地迭代对象,那么你可以使用用于递归地迭代对象的CCD_ 4。

下面是一个工作示例:

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>

这里还有另一种可能性,利用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);

试试这样的东西:

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.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>

我已经完成了……我使用了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>

最新更新