Reputation: 1434
I want to merge a selector split by another selector.
My actual selector looks like $('.JS_toggle-submenu')
<li class="JS_toggle-submenu" data-submenu="#submenu-l2-foo">…</li>
<h2 class="JS_toggle-submenu" data-submenu="#submenu-l2-foo">…</h2>
<p class="JS_toggle-submenu" data-submenu="#submenu-l3-bar">…</p>
<h3 class="JS_toggle-submenu" data-submenu="#submenu-l3-bar">…</h3>
And would like to filter it to the first of each data-submenu like
$('.JS_toggle-submenu').filter('[data=GROUPING]:first')
<li class="JS_toggle-submenu" data-submenu="#submenu-l2-foo">…</li>
<p class="JS_toggle-submenu" data-submenu="#submenu-l3-bar">…</p>
Of course, I'm not looking for a static solution.
I don't see an efficient way to do this, it seems I need to loop again but I would prefer to avoid, but maybe someone here have a magical solution?
//EDIT:
I need a IE7/8 compatibility, that's why I didn't choose the indexOf solution, but I omitted to explain in my original question.
I compared the both result here http://jsperf.com/filter-loop-or-regex same Ops/sec.
Upvotes: 1
Views: 67
Reputation: 24965
Here's using a jquery each loop: http://jsfiddle.net/3y69usxv/
var submenus = [];
var firstMenus = [];
$('.JS_toggle-submenu').each(function(){
var $this = $(this);
if (submenus.indexOf($this.data('submenu')) < 0) {
submenus.push($this.data('submenu'));
firstMenus.push($this);
}
});
console.log(firstMenus);
Upvotes: 1
Reputation: 78525
You could filter the IDs out based on an array of objects you'd found before. Something like:
// Array of IDs already found
var existing = [];
// Regex to pull the level number from the data attribute
var regexp = new RegExp("#submenu-l([0-9]+)-(.*?)", "i");
console.log($(".JS_toggle-submenu[data-submenu^='#submenu-l']").filter(function() {
// Get the ID
var id = regexp.exec($(this).data("submenu"))[1];
// If we have already found a DOM element for this level, continue
if(existing[id]) return false;
// Otherwise add it to the existing found elements...
existing[id] = true;
// Allow it to pass through the filter
return true;
}).get());
Upvotes: 1