I have a javascript structure like below (nested arrays of objects)
我有一个像下面的javascript结构(嵌套的对象数组)
var categoryGroups = [
{
Id: 1, Categories: [
{ Id: 1 },
{ Id: 2 },
]
},
{
Id: 2, Categories: [
{ Id: 100 },
{ Id: 200 },
]
}
]
I want to find a child Category object matching an Id, assuming the Category Id's are all unique.
我想找到一个匹配Id的子类别对象,假设类别ID都是唯一的。
I've got this below, but was wondering if there is a more concise way of doing it:
我在下面有这个,但是想知道是否有更简洁的方法:
var category, categoryGroup, found = false;
for (i = 0; i < categoryGroups.length ; i++) {
categoryGroup = categoryGroups[i];
for (j = 0; j < categoryGroup.Categories.length; j++) {
category = categoryGroup.Categories[j];
if (category.Id === id) {
found = true;
break;
}
}
if (found) break;
}
5 个解决方案
#1
4
Caveat: This uses a couple of Array.prototype
functions that were only added in ECMAScript 5 and thus will not work with older browsers unless you polyfill them.
警告:这使用了一些仅在ECMAScript 5中添加的Array.prototype函数,因此除非您对它们进行填充,否则它们将无法与旧版浏览器一起使用。
You can loop over all first-level objects in your array, and then filter the categories based on your condition and collect all matches in an array. Your final result will be the first element in the array of matches (no match found if array is empty).
您可以循环遍历阵列中的所有第一级对象,然后根据您的条件过滤类别并收集数组中的所有匹配项。您的最终结果将是匹配数组中的第一个元素(如果数组为空,则找不到匹配项)。
var matches = [];
var needle = 100; // what to look for
arr.forEach(function(e) {
matches = matches.concat(e.Categories.filter(function(c) {
return (c.Id === needle);
}));
});
console.log(matches[0] || "Not found");
JSFiddle: http://jsfiddle.net/b7ktf/1/
JSFiddle:http://jsfiddle.net/b7ktf/1/
References:
参考文献:
Array.prototype.forEach
Array.prototype.concat
Array.prototype.filter
Array.prototype.forEach Array.prototype.concat Array.prototype.filter
#2
2
Easy way using lodash library of NodeJS (assuming you are using NodeJS):
使用NodeJS的lodash库的简单方法(假设您使用的是NodeJS):
const _ = require('lodash');
let category ;
let categoryGroup = _.find(categoryGroups, (element)=>{
category = _.find(element.Categories, {Id : 100});
return category;
});
console.log(categoryGroup); // The category group which has the sub category you are looking for
console.log(category); // The exact category you are looking for
#3
1
check the code in the fiddle
检查小提琴中的代码
var categoryGroups = [
{
Id: 1, Categories: [
{ Id: 1 },
{ Id: 2 },
]
},
{
Id: 2, Categories: [
{ Id: 100 },
{ Id: 200 },
]
}
]
var id = 100;
var x = 'not found';
var category, categoryGroup, found = false;
for (i = 0; i < categoryGroups.length ; i++) {
categoryGroup = categoryGroups[i];
for (j = 0; j < categoryGroup.Categories.length; j++) {
category = categoryGroup.Categories[j];
if (category.Id == id) {
var x = category.Id;
found = true;
break;
}
}
if (found) break;
}
alert(x);
The above code checks if id = 100 is found in the array. If found will alert the value else alerts that its not found. value '100' has been hardcoded for the sake of demo
上面的代码检查数组中是否找到id = 100。如果发现将提醒值,否则警报未找到。为了演示,值'100'已被硬编码
#4
1
You could wrap it inside a function to get rid of the awkward break;
syntax and you can load each element into a variable inside the for(;;)
construct to shave off a few lines.
你可以将它包装在一个函数中以摆脱尴尬的中断;语法,您可以将每个元素加载到for(;;)构造内的变量中,以削减几行。
function subCategoryExists(groups, id)
{
for (var i = 0, group; group = groups[i]; ++i) {
for (var k = 0, category; category = group.Categories[k]; ++k) {
if (category.Id == id) {
return true;
}
}
}
return false;
}
var found = subCategoryExists(categoryGroups, 100);
#5
0
You could use underscore:
你可以使用下划线:
var cat = _(categoryGroups).
chain().
pluck('Categories').
flatten().
findWhere({Id: 2}).
value();
What I'm doing here is that I'm extracting all Categories
values in a single array and then grepping for the correct categories.
我在这里做的是我在一个数组中提取所有Categories值,然后在grepping中找到正确的类别。
EDIT: sorry, didn't get your question right the first time. As the comments suggest, you might not want to use underscore just for that, but that's how I would do it :)
编辑:对不起,第一次没问题。正如评论所暗示的那样,你可能不想仅仅使用下划线,但这就是我要做的:)
#1
4
Caveat: This uses a couple of Array.prototype
functions that were only added in ECMAScript 5 and thus will not work with older browsers unless you polyfill them.
警告:这使用了一些仅在ECMAScript 5中添加的Array.prototype函数,因此除非您对它们进行填充,否则它们将无法与旧版浏览器一起使用。
You can loop over all first-level objects in your array, and then filter the categories based on your condition and collect all matches in an array. Your final result will be the first element in the array of matches (no match found if array is empty).
您可以循环遍历阵列中的所有第一级对象,然后根据您的条件过滤类别并收集数组中的所有匹配项。您的最终结果将是匹配数组中的第一个元素(如果数组为空,则找不到匹配项)。
var matches = [];
var needle = 100; // what to look for
arr.forEach(function(e) {
matches = matches.concat(e.Categories.filter(function(c) {
return (c.Id === needle);
}));
});
console.log(matches[0] || "Not found");
JSFiddle: http://jsfiddle.net/b7ktf/1/
JSFiddle:http://jsfiddle.net/b7ktf/1/
References:
参考文献:
Array.prototype.forEach
Array.prototype.concat
Array.prototype.filter
Array.prototype.forEach Array.prototype.concat Array.prototype.filter
#2
2
Easy way using lodash library of NodeJS (assuming you are using NodeJS):
使用NodeJS的lodash库的简单方法(假设您使用的是NodeJS):
const _ = require('lodash');
let category ;
let categoryGroup = _.find(categoryGroups, (element)=>{
category = _.find(element.Categories, {Id : 100});
return category;
});
console.log(categoryGroup); // The category group which has the sub category you are looking for
console.log(category); // The exact category you are looking for
#3
1
check the code in the fiddle
检查小提琴中的代码
var categoryGroups = [
{
Id: 1, Categories: [
{ Id: 1 },
{ Id: 2 },
]
},
{
Id: 2, Categories: [
{ Id: 100 },
{ Id: 200 },
]
}
]
var id = 100;
var x = 'not found';
var category, categoryGroup, found = false;
for (i = 0; i < categoryGroups.length ; i++) {
categoryGroup = categoryGroups[i];
for (j = 0; j < categoryGroup.Categories.length; j++) {
category = categoryGroup.Categories[j];
if (category.Id == id) {
var x = category.Id;
found = true;
break;
}
}
if (found) break;
}
alert(x);
The above code checks if id = 100 is found in the array. If found will alert the value else alerts that its not found. value '100' has been hardcoded for the sake of demo
上面的代码检查数组中是否找到id = 100。如果发现将提醒值,否则警报未找到。为了演示,值'100'已被硬编码
#4
1
You could wrap it inside a function to get rid of the awkward break;
syntax and you can load each element into a variable inside the for(;;)
construct to shave off a few lines.
你可以将它包装在一个函数中以摆脱尴尬的中断;语法,您可以将每个元素加载到for(;;)构造内的变量中,以削减几行。
function subCategoryExists(groups, id)
{
for (var i = 0, group; group = groups[i]; ++i) {
for (var k = 0, category; category = group.Categories[k]; ++k) {
if (category.Id == id) {
return true;
}
}
}
return false;
}
var found = subCategoryExists(categoryGroups, 100);
#5
0
You could use underscore:
你可以使用下划线:
var cat = _(categoryGroups).
chain().
pluck('Categories').
flatten().
findWhere({Id: 2}).
value();
What I'm doing here is that I'm extracting all Categories
values in a single array and then grepping for the correct categories.
我在这里做的是我在一个数组中提取所有Categories值,然后在grepping中找到正确的类别。
EDIT: sorry, didn't get your question right the first time. As the comments suggest, you might not want to use underscore just for that, but that's how I would do it :)
编辑:对不起,第一次没问题。正如评论所暗示的那样,你可能不想仅仅使用下划线,但这就是我要做的:)