I'm trying to select a grand child from an array in an array.
If it was C# I would have wrote something like below
SubSteps.Select(item => item.First(subitem => subitem == 1)).First();
I have code that works, but I'm not sure it is the best way to do it:
ko.utils.arrayFirst(ko.utils.arrayFirst(self.SubSteps(),
function (item) {
return ko.utils.arrayFirst(item.SubSteps(),
function (subItem) { return subItem.InternalName == localStorage.getItem('lastWizardPage'); });
}).SubSteps(), function (item) {
return item.InternalName == localStorage.getItem('lastWizardPage');
})
Is there a method I can use that I've never heard of perhaps?
2 Answers 2
Interesting question.
First off, your indentation is terrible, your code is far more readable like this:
ko.utils.arrayFirst(ko.utils.arrayFirst(self.SubSteps(),
function(item) {
return ko.utils.arrayFirst(item.SubSteps(),
function(subItem) {
return subItem.InternalName == localStorage.getItem('lastWizardPage');
});
}).SubSteps(), function(item) {
return item.InternalName == localStorage.getItem('lastWizardPage');
})
Second, you are retrieving your subitem twice, because you loose track of it, simply use a 'local global' and assign your subitem to it.
var needle, found;
ko.utils.arrayFirst(self.SubSteps(),
function(item) {
return ko.utils.arrayFirst(item.SubSteps(),
function(subItem) {
found = subItem.InternalName == localStorage.getItem('lastWizardPage');
if(found) {
needle = subItem;
}
return found;
});
});
or, if you dont mind some sorcery (don't do this at work!)
var needle, found;
ko.utils.arrayFirst(self.SubSteps(),
function(item) {
return ko.utils.arrayFirst(item.SubSteps(),
function(subItem) {
found = subItem.InternalName == localStorage.getItem('lastWizardPage');
return found && (needle = subItem), found;
});
});
Furthemore, you should consider caching localStorage.getItem('lastWizardPage')
and you should consider implementing old skool loops so that you can exit immediately.
-
\$\begingroup\$ Thank you. The intendention is better in my IDE, but broke here. About the rest of the code worked really good. Thank you! \$\endgroup\$Pochen– Pochen2014年10月03日 11:27:16 +00:00Commented Oct 3, 2014 at 11:27
It looks like you could use recursion to simplify your code, unless the grandchildren have children that you want to avoid, this should work.
function findLastWizard(arr) {
var subArrayOrItem = ko.utils.arrayFirst(arr, function(item) {
return item.InternalName == localStorage.getItem('lastWizardPage');
});
if(subArrayOrItem.SubSteps) {
return findLastWizard(subArrayOrItem.SubSteps());
}
return subArrayOrItem;
}
findLastWizard(self.SubSteps())