这是我拥有的一些JSON数据:
[
{
"name" : "X",
"children" : [
{
"name" : "Y"
},
{
"name" : "Z"
}
]
},
{
"name" : "A",
"options" : [
{
"children" : [
{
"name" : "B"
},
{
"name" : "C"
}
]
},
{
"children" : [
{
"name" : "D"
},
{
"name" : "E"
}
]
}
],
"children" : [
{
"name" : "F"
},
{
"name" : "G"
}
]
}
]
我想检索与我要查找的名称匹配的对象。
我的问题是,由于有数据数组,
获得匹配对象的最佳算法是什么:
{
"name" : F
}
例如,如果我正在寻找 F
答案 0 :(得分:1)
您可以检查上交的项目是否不是对象,然后返回undefined,如果找到所需名称,则返回该对象,否则从对象中迭代值并检查嵌套的对象。
方法:
null
的对象的模式,Object.values
用于获取对象的所有值,Array#some
,如果返回值为truthy(在这种情况下,找到一个对象),则允许短路,
function getObject(object, name) {
var temp;
if (!object || typeof object !== 'object') return;
if (object.name === name) return object;
Object.values(object).some(o => temp = getObject(o, name));
return temp;
}
var data = [{ name: 'X', children: [{ name: 'Y' }, { name: 'Z' }] }, { name: 'A', options: [{ children: [{ name: 'B' }, { name: 'C' }] }, { children: [{ name: 'D' }, { name: 'E' }] }], children: [{ name: 'F' }, { name: 'G' }] }];
console.log(getObject(data, 'F'));
console.log(getObject(data, 'A'));
.as-console-wrapper { max-height: 100% !important; top: 0; }
答案 1 :(得分:0)
更新
下面是一个递归代码,应该测试传入的参数是一个数组(并检查每个元素)还是一个对象,并检查“ name”属性,如果不是我们想要的,则运行相同的递归每个属性的方法。这是代码:
retrieveObjectWithName(obj, name)
{
// if incoming object has property name and it matches our search name
if (obj.name === name) {
return obj;
}
// if incoming object is an array then we iterate through it and test each element
if (Array.isArray(obj)){
for (var i = 0; i < obj.length; i++) {
var result = retrieveObjectWithName(obj[i], name);
if (result) {
return result;
}
}
}
// if the incoming object is an object then we iterate through each property and test each property
for (var property in obj) {
if (object.hasOwnProperty(property)) {
var result = retrieveObjectWithName(obj[property], name);
if (result) {
return result;
}
}
}
// nothing was found (at least on this level)
return null;
}
答案 2 :(得分:0)
此代码可以永远嵌套。
const data = [{
name: 'jamal 1',
options: [{
children: [{
name: 'jamal 1 1 1',
}, {
name: 'jamal 1 1 2',
}],
}, {
children: [{
name: 'jamal 1 2 1',
}, {
name: 'jamal 1 2 2',
}],
}],
}, {
name: 'jamal 2',
children: [{
name: 'jamal 2 1',
}, {
name: 'jamal 2 2',
}],
}];
function compare(obj, comp) {
for (const key in comp) {
console.log(obj[key], comp[key]);
if (obj.hasOwnProperty(key)) {
if (obj[key] != comp[key]) {
return false;
}
} else {
return false;
}
}
return true;
}
function search(object, query) {
for (const item of object) {
if (compare(item, query)) {
return item;
} else if (Array.isArray(item.options)) {
const result = search(item.options, query);
if (result) return result;
} else if (Array.isArray(item.children)) {
const result = search(item.children, query);
if (result) return result;
}
}
return null;
}
console.log(search(data, {name: 'jamal 1 1 2'})); // result {name: 'jamal 1 1 2'}
抱歉,该名称仅用于测试:)
答案 3 :(得分:0)
好吧,根据帖子,我无法避免存储返回值并检查它是否为null。我坚决做到这一点,但我发现这很脏而且没有优化。
function findField(fieldName, scope = fields){
let i;
let result;
for(i=0; i < scope.length; i++){
if(scope[i].name === fieldName){
return scope[i];
}
else if ("options" in scope[i]){
let j;
for(j=0; j < scope[i].options.length; j++){
result = findField(fieldName, scope[i].options[j].children)
if(result) return result
}
}
else {
result = findField(fieldName, scope[i].children)
if(result) return result
}
}
return null
}
感谢您的帮助。