在深度嵌套的对象数组中搜索单个键
Searching deeply nested object array for a single key
我正在尝试搜索一个深度嵌套的数组并查找其中是否存在某个键。我已经编写了一段进行遍历的代码,但是因为它不是递归的(仅自调用)所以它不能 return 无论它是否找到任何东西。它只是 returns undefined
因为它在一次传递中到达了函数的末尾。
我想知道是否有一种方法可以让我在第一次出现特定键时 return true
。
这是我到目前为止一直在使用的 JS bin:
https://jsbin.com/qaxuwajuso/edit?js,console
这里直接粘贴上面示例中的代码:
function traverse(item, key) {
if (typeof item === 'object' && !Array.isArray(item) && item !== null) {
// Object
for (let itemKey in item) {
if (itemKey === key) {
// Is it possible to return true and break out of the function here?
console.log('found the key: ' + itemKey + ' With value: ' + item[itemKey]);
}
traverse(item[itemKey], key);
}
} else if (Array.isArray(item)) {
// Array
for (let i = 0; i < item.length; ++i) {
traverse(item[i], key);
}
}
}
如有任何帮助,我们将不胜感激。感谢您的宝贵时间!
当然你只需要return某种标志来触发循环停止
/*
* I am trying to search the following json array for any occurance of the key "statePath".
* In a perfect world I would be able to find the first occurance, and return true from the
* function.
*
* The following data is not real, I was just trying to write as much nested stuff as possible
* to test that it traverses as far as needed.
*/
const data = [
{
id: '2144d998-4c33-4b03-93d2-f6c675b24508',
element: 'div',
props: {
className: 'testing',
name: [
{
first: 'John',
last: {
statePath: 'lastName',
anArray: [
{
anObject: {
anotherArray: [
{
doesItWork: {
statePath: 'hello',
},
},
],
},
},
],
},
},
{
first: 'Jane',
last: {
statePath: 'lastName',
},
},
],
},
children: 'hi',
},
];
function traverse(item, key) {
if (typeof item === 'object' && !Array.isArray(item) && item !== null) {
// Object
for (let itemKey in item) {
if (itemKey === key) {
console.log('found the key: ' + itemKey + ' With value: ' + item[itemKey]);
// not sure what you want the end "return" of the func to be, I'm returning the value. You could return true here instead, you could return a reference to the parent object, lots of possibilities
return item[itemKey];
}
var found = traverse(item[itemKey], key);
if (found !== undefined) return found;
// otherwise keep looking
}
} else if (Array.isArray(item)) {
// Array
for (let i = 0; i < item.length; ++i) {
var found = traverse(item[i], key);
if (found !== undefined) return found;
}
}
}
var value = traverse(data, 'statePath');
console.log("value is " + value);
您可以使用 for...in
并将结果存储在一个变量中,然后在再次调用函数之前检查该变量,如果找到值则中断循环。
const data = [{"id":"2144d998-4c33-4b03-93d2-f6c675b24508","statePath":"div","props":{"className":"testing","name":[{"first":"John","last":{"statePath":"lastName","anArray":[{"anObject":{"anotherArray":[{"doesItWork":{"statePath":"hello"}}]}}]}},{"first":"Jane","last":{"statePath":"lastName"}}]},"children":"hi"}]
function traverse(item, key) {
let result = false;
for (var i in item) {
if (i == key) {
result = true;
break;
}
if (typeof item[i] == 'object' && !result) {
result = traverse(item[i], key)
}
}
return result
}
console.log(traverse(data, 'statePath'))
我的变体:
const data = [{id: '2144d998-4c33-4b03-93d2-f6c675b24508', element: 'div', props: {className: 'testing', name: [{first: 'John', last: {statePath3: 'lastName', anArray: [{anObject: {anotherArray: [{doesItWork: {statePath1: 'hello',},},],},},],},}, {first: 'Jane', last: {statePath: 'lastName',},},],}, children: 'hi',},];
function traverse(data, find) {
for (let k in data) {
let deepHaveKey = typeof data[k] === 'object' && traverse(data[k], find)
if (find === k || deepHaveKey)
return true
}
return false
}
console.log(traverse(data, 'statePath')); // true
console.log(traverse(data, 'state')); // false
我正在尝试搜索一个深度嵌套的数组并查找其中是否存在某个键。我已经编写了一段进行遍历的代码,但是因为它不是递归的(仅自调用)所以它不能 return 无论它是否找到任何东西。它只是 returns undefined
因为它在一次传递中到达了函数的末尾。
我想知道是否有一种方法可以让我在第一次出现特定键时 return true
。
这是我到目前为止一直在使用的 JS bin:
https://jsbin.com/qaxuwajuso/edit?js,console
这里直接粘贴上面示例中的代码:
function traverse(item, key) {
if (typeof item === 'object' && !Array.isArray(item) && item !== null) {
// Object
for (let itemKey in item) {
if (itemKey === key) {
// Is it possible to return true and break out of the function here?
console.log('found the key: ' + itemKey + ' With value: ' + item[itemKey]);
}
traverse(item[itemKey], key);
}
} else if (Array.isArray(item)) {
// Array
for (let i = 0; i < item.length; ++i) {
traverse(item[i], key);
}
}
}
如有任何帮助,我们将不胜感激。感谢您的宝贵时间!
当然你只需要return某种标志来触发循环停止
/*
* I am trying to search the following json array for any occurance of the key "statePath".
* In a perfect world I would be able to find the first occurance, and return true from the
* function.
*
* The following data is not real, I was just trying to write as much nested stuff as possible
* to test that it traverses as far as needed.
*/
const data = [
{
id: '2144d998-4c33-4b03-93d2-f6c675b24508',
element: 'div',
props: {
className: 'testing',
name: [
{
first: 'John',
last: {
statePath: 'lastName',
anArray: [
{
anObject: {
anotherArray: [
{
doesItWork: {
statePath: 'hello',
},
},
],
},
},
],
},
},
{
first: 'Jane',
last: {
statePath: 'lastName',
},
},
],
},
children: 'hi',
},
];
function traverse(item, key) {
if (typeof item === 'object' && !Array.isArray(item) && item !== null) {
// Object
for (let itemKey in item) {
if (itemKey === key) {
console.log('found the key: ' + itemKey + ' With value: ' + item[itemKey]);
// not sure what you want the end "return" of the func to be, I'm returning the value. You could return true here instead, you could return a reference to the parent object, lots of possibilities
return item[itemKey];
}
var found = traverse(item[itemKey], key);
if (found !== undefined) return found;
// otherwise keep looking
}
} else if (Array.isArray(item)) {
// Array
for (let i = 0; i < item.length; ++i) {
var found = traverse(item[i], key);
if (found !== undefined) return found;
}
}
}
var value = traverse(data, 'statePath');
console.log("value is " + value);
您可以使用 for...in
并将结果存储在一个变量中,然后在再次调用函数之前检查该变量,如果找到值则中断循环。
const data = [{"id":"2144d998-4c33-4b03-93d2-f6c675b24508","statePath":"div","props":{"className":"testing","name":[{"first":"John","last":{"statePath":"lastName","anArray":[{"anObject":{"anotherArray":[{"doesItWork":{"statePath":"hello"}}]}}]}},{"first":"Jane","last":{"statePath":"lastName"}}]},"children":"hi"}]
function traverse(item, key) {
let result = false;
for (var i in item) {
if (i == key) {
result = true;
break;
}
if (typeof item[i] == 'object' && !result) {
result = traverse(item[i], key)
}
}
return result
}
console.log(traverse(data, 'statePath'))
我的变体:
const data = [{id: '2144d998-4c33-4b03-93d2-f6c675b24508', element: 'div', props: {className: 'testing', name: [{first: 'John', last: {statePath3: 'lastName', anArray: [{anObject: {anotherArray: [{doesItWork: {statePath1: 'hello',},},],},},],},}, {first: 'Jane', last: {statePath: 'lastName',},},],}, children: 'hi',},];
function traverse(data, find) {
for (let k in data) {
let deepHaveKey = typeof data[k] === 'object' && traverse(data[k], find)
if (find === k || deepHaveKey)
return true
}
return false
}
console.log(traverse(data, 'statePath')); // true
console.log(traverse(data, 'state')); // false