Can E4X Have An Array Passed To It?
Question
Say we have the following XML:
<people>
<person>
<name>Jake</name>
<skills>
<skill>JavaScript</skill>
<skill>HTML</skill>
<skill>Flex</skill>
<skill>CSS</skill>
</skills>
</person>
<person>
<name>John</name>
<skills>
<skill>C++</skill>
<skill>Foxpro</skill>
</skills>
</person>
<person>
<name>Josh</name>
<skills>
<skill>JavaScript</skill>
<skill>XML</skill>
<skill>Flex</skill>
</skills>
</person>
</people>
What I want to be able to do with E4X is find all person objects that match a list/array of skills I pass it. So, say I want find all people with either HTML or JavaScript skills.
I know I can do:
people.person.(descendants("skill").contains("HTML"))
or
people.person.(descendants("skill").contains("JavaScript"))
But I really want (/need) to do it one line (it's part of a XMLListCollection filter function in Flex).
Something like this would be ideal
people.person.(descendants("skill").contains("HTML","JavaScript"))
Although I tried variations on that theme and got nowhere. What would be great would be:
people.person.(descendants("skill").in("HTML", "JavaScript"))
or something like that.
Anybody know if what I'm doing is possible?
I really want to avoid adding my own loops in there.
Jake
Solution
Didn't verify this with the compiler but this should work...
people.person.(descendants("skill").contains("HTML") || descendants("skill").contains("JavaScript"))
Here's another take —
If you want to check against an Array within the E4X statement, I guess you're out of luck. There is one possible workaround though, but it involves using a custom function inside the E4X, and simply moving the loop outside of your main code block. Kind of redundant, if you really want to avoid loops.
var skillsArray:Array = ["HTML", "JavaScript"];
var peopleWithSkills:XMLList = people.person.(matchSkills(descendants("skill"), skillsArray));
function matchSkills(xmlList:XMLList, skillsArray:Array):Boolean
{
for each (var personSkill:XML in xmlList)
{
if (skillsArray.indexOf(personSkill.toString()) > -1)
{
return true;
}
}
return false;
}
My best suggestion would be to really look into your heart and decide whether you need to avoid the loops, or if you just want to avoid them. ;)