在数组中的数组中查找元素,并在父对象中查找 return 元素
Find element in array inside array and return element with parent object
鉴于...
var a = [{ b: [{ i: 2 }, { i: 3 }] }, { b: [{ i: 4 }, { i: 5 }] }, { b: [{ i: 6 }, { i: 7 }] }];
查找对象的好方法是什么,例如,使用 i = 5
加上包含它所在的数组的对象?
因此,结果将是两个引用...
var r0 = { "i": 5 };
var r1 = { "b": [{ "i": 4 }, { "i": 5 } ]};
使用箭头 functions:
var a = [{ b: [{ i: 2 }, { i: 3 }] }, { b: [{ i: 4 }, { i: 5 }] }, { b: [{ i: 6 }, { i: 7 }] }];
var result = a.filter(x => x.b.find(b => b.i == 5));
console.log(result)
或使用普通函数:
var a = [{ b: [{ i: 2 }, { i: 3 }] }, { b: [{ i: 4 }, { i: 5 }] }, { b: [{ i: 6 }, { i: 7 }] }];
var result = a.filter(function (x) {
return x.b.find(function(b) {
return b.i == 5;
});
});
console.log(result);
你可以用 forEach
:
var a = [{ b: [{ i: 2 }, { i: 3 }] }, { b: [{ i: 4 }, { i: 5 }] }, { b: [{ i: 6 }, { i: 7 }] }];
var r0;
var r1;
a.forEach(function(item){
item.b.forEach(function(inner){
if(inner.i==5){
r0 = inner; r1 = item;
}
});
});
console.log(r0);
console.log(r1);
我认为解决方案可能会根据您的实际背景而有所不同,例如您考虑的因素是最重要的,例如时间,space,read/write效率等
下面是两种基本用法的解决方案:
var a = [{ b: [{ i: 2 }, { i: 3 }] }, { b: [{ i: 4 }, { i: 5 }] }, { b: [{ i: 6 }, { i: 7 }] }]
//The commom way: it has to loop whole array for each query
queryItem1 = function(searchTarget, searchVal) {
return searchTarget.filter(
function(val){
return val.b.filter(function(item){return item.i===searchVal;}).length>0;
}
)
}
console.log('---common way----')
console.log(queryItem1(a, 5))
console.log('---end----')
//Considering `query` efficiency;
//build index once, then query by one step instead of loop
buildIndexes = function(target) {
let indexes = new Object();
for(index in target) {
for(itemIndex in target[index].b) {
let queryVal = target[index].b[itemIndex].i;
let queryIndex = index;
if(!indexes[queryVal]) {
indexes[queryVal] = [];
}
indexes[queryVal].push(queryIndex);
}
}
return indexes;
}
console.log('---consider `query` efficiency way----')
indexes = buildIndexes(a)
//console.log(indexes) //display index tree
console.log('---test case 1----')
console.log(indexes[5]) //if query vale is 5, get the index, then call like a[indexes[5][0]]
console.log(a[indexes[5][0]])
console.log('---test case 2----')
console.log(indexes[6]) //if query vale is 6, get the index, then call like a[indexes[6][0]]
console.log(a[indexes[6][0]])
console.log('---end----')
两次迭代都可以采用 Array#some
,因为如果找到,迭代会停止返回 true
。
这个提议returns第一个找到条件为true
的元素。
var array = [{ b: [{ i: 2 }, { i: 3 }] }, { b: [{ i: 4 }, { i: 5 }] }, { b: [{ i: 6 }, { i: 7 }] }],
i = 5,
r0, r1;
array.some(function (a) {
return a.b.some(function (b) {
if (b.i === i) {
r0 = b;
r1 = a;
return true;
}
});
});
console.log(r0);
console.log(r1);
.as-console-wrapper { max-height: 100% !important; top: 0; }
鉴于...
var a = [{ b: [{ i: 2 }, { i: 3 }] }, { b: [{ i: 4 }, { i: 5 }] }, { b: [{ i: 6 }, { i: 7 }] }];
查找对象的好方法是什么,例如,使用 i = 5
加上包含它所在的数组的对象?
因此,结果将是两个引用...
var r0 = { "i": 5 };
var r1 = { "b": [{ "i": 4 }, { "i": 5 } ]};
使用箭头 functions:
var a = [{ b: [{ i: 2 }, { i: 3 }] }, { b: [{ i: 4 }, { i: 5 }] }, { b: [{ i: 6 }, { i: 7 }] }];
var result = a.filter(x => x.b.find(b => b.i == 5));
console.log(result)
或使用普通函数:
var a = [{ b: [{ i: 2 }, { i: 3 }] }, { b: [{ i: 4 }, { i: 5 }] }, { b: [{ i: 6 }, { i: 7 }] }];
var result = a.filter(function (x) {
return x.b.find(function(b) {
return b.i == 5;
});
});
console.log(result);
你可以用 forEach
:
var a = [{ b: [{ i: 2 }, { i: 3 }] }, { b: [{ i: 4 }, { i: 5 }] }, { b: [{ i: 6 }, { i: 7 }] }];
var r0;
var r1;
a.forEach(function(item){
item.b.forEach(function(inner){
if(inner.i==5){
r0 = inner; r1 = item;
}
});
});
console.log(r0);
console.log(r1);
我认为解决方案可能会根据您的实际背景而有所不同,例如您考虑的因素是最重要的,例如时间,space,read/write效率等
下面是两种基本用法的解决方案:
var a = [{ b: [{ i: 2 }, { i: 3 }] }, { b: [{ i: 4 }, { i: 5 }] }, { b: [{ i: 6 }, { i: 7 }] }]
//The commom way: it has to loop whole array for each query
queryItem1 = function(searchTarget, searchVal) {
return searchTarget.filter(
function(val){
return val.b.filter(function(item){return item.i===searchVal;}).length>0;
}
)
}
console.log('---common way----')
console.log(queryItem1(a, 5))
console.log('---end----')
//Considering `query` efficiency;
//build index once, then query by one step instead of loop
buildIndexes = function(target) {
let indexes = new Object();
for(index in target) {
for(itemIndex in target[index].b) {
let queryVal = target[index].b[itemIndex].i;
let queryIndex = index;
if(!indexes[queryVal]) {
indexes[queryVal] = [];
}
indexes[queryVal].push(queryIndex);
}
}
return indexes;
}
console.log('---consider `query` efficiency way----')
indexes = buildIndexes(a)
//console.log(indexes) //display index tree
console.log('---test case 1----')
console.log(indexes[5]) //if query vale is 5, get the index, then call like a[indexes[5][0]]
console.log(a[indexes[5][0]])
console.log('---test case 2----')
console.log(indexes[6]) //if query vale is 6, get the index, then call like a[indexes[6][0]]
console.log(a[indexes[6][0]])
console.log('---end----')
两次迭代都可以采用 Array#some
,因为如果找到,迭代会停止返回 true
。
这个提议returns第一个找到条件为true
的元素。
var array = [{ b: [{ i: 2 }, { i: 3 }] }, { b: [{ i: 4 }, { i: 5 }] }, { b: [{ i: 6 }, { i: 7 }] }],
i = 5,
r0, r1;
array.some(function (a) {
return a.b.some(function (b) {
if (b.i === i) {
r0 = b;
r1 = a;
return true;
}
});
});
console.log(r0);
console.log(r1);
.as-console-wrapper { max-height: 100% !important; top: 0; }