PDA

View Full Version : Loop through collection and create one element for each difference



VIPStephan
Jul 27th, 2012, 01:42 PM
OK, Iíve kinda got a mental block at the moment and donít even know how to formulate something to use in search engines which is why Iím asking here:

Letís say I have a few elements that have something in common but also a difference like:


<div class="a b"></div>
<div class="a b"></div>
<div class="a c"></div>
<div class="a d"></div>

All divs share the same class ďaĒ and their difference may or may not be the second class. I want to append an element for each type of difference, i. e. in the above example three elements would be added. The class ďaĒ is the trigger for the loop (the collection to loop through) and the second class is the type according to which one element is to be added.

Whatís the logic for that?
Note: Iím doing this with jQuery but a regular JS solution would probably still help me to get in the right direction. I guess I can construct something with jQuery out of it once Iím clear about the idea.

vwphillips
Jul 27th, 2012, 02:48 PM
there are only two changes of class in your example


<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">

<head>
<title></title>
</head>

<body>
<div class="a b"></div>
<div class="a b"></div>
<div class="a c"></div>
<div class="a d"></div>
<div class="a c"></div>
<script> vic=0; </script>
<form name=Show id=Show style="position:absolute;visibility:visible;top:700px;left:0px;" >
<input size=100 name=Show0 >
<input size=10 name=Show1 >
<input size=10 name=Show2 >
<input size=10 name=Show3 >
<input size=10 name=Show4 >
<input size=10 name=Show5 >
<input size=10 name=Show6 >
<input size=10 name=Show7 >
<input size=10 name=Show8 >
<input size=10 name=Show9 ><br>
<textarea name=TA rows=1 cols=100 ></textarea>
</form>

<script type="text/javascript">
/*<![CDATA[*/
function bycls(nme){
for (var reg=new RegExp('\\W'+nme+'\\W'),els=document.getElementsByTagName('*'),ary=[],z0=0,z1=1,s,cnt=0;z0<els.length;z0++){
if(reg.test(' '+els[z0].className+' ')){
ary.push(els[z0]);
}
}
s=ary[0].className+',';
for (;z1<ary.length;z1++){
if (s.indexOf(ary[z1].className+',')<0){
cnt++;
}
s+=ary[z1].className+',';
}
document.Show.Show0.value=cnt;
return ary;
}

bycls('a')
/*]]>*/
</script>

</body>

</html>

VIPStephan
Jul 27th, 2012, 03:13 PM
Sorry, maybe I didnít express myself clearly enough. Class a is just an example for something all elements have in common. Classes b, c, and d (or any other) are the classes that differentiate certain elements. What I need now is that for each different class (in this example b, c, and d) that occurs in the document I need to add one element, e. g.:


<!-- outcome -->
<div class="a b"></div>
<div class="a b"></div>
<div class="a c"></div>
<div class="a d"></div>

<span id="example0">class b exists</span> <!-- even though there are two (or more) elements with class ďbĒ, just one element is added -->
<span id="example1">class c exists</span>
<span id="example2">class d exists</span>

DrDOS
Jul 27th, 2012, 03:52 PM
You need what's called an 'exaustive' method, one that goes over all the possibilities without either omitting or duplicating the results. So you need to make up a list as you go along, of all the things you have already tried. Say your classes are ordered a,b,c,d etc, where in your example 'a' is the 'class of all classes'. In your case it's simple, just a conditional that says in effect, this is in the array, don't do it again. It can be made more sophisticated to cover more combinations, but you need to treat the classes as being an ordered set to make it multilevel.

VIPStephan
Jul 27th, 2012, 04:16 PM
Well, I think I’ve hacked something together, although I don’t know if that’s the best solution. It certainly doesn’t allow more than two classes in the attribute with this solution:


$('.a').each(function(i) {
var x = $(this).attr('class');
x = x.replace('a ','');
if($(x).length == 0) {
$('body').append($('<span>', {'id': x}));
}
});

jQuery makes it easy to retreive elements by class names, loop over them, and convert strings to objects. I just need to check if an object with the class already exists and only add an element if not.

Thanks to both of you anyway because asking a question here always makes you think about things differently while formulating the question.