views:

175

answers:

6

Hi All,

I am trying to remove all the rows from a table EXCEPT the matched rows:

This code removes the rows that I in fact want to keep -

$("table#traffic").each(function() {
    $("td:contains('" + selected_text + "')").parent().remove();
});

I basically want to do the opposite of the above.

A: 

there's a .not function you might be able to work with. http://docs.jquery.com/Traversing/not#expr

David
A: 

I'm disappointed the above solutions aren't specific to his particular table and are, in fact, checking any and all table rows. This might not be the desired effect.

$("table#traffic td:not(:contains('" + selected_text + "'))").parent().remove();
cballou
+1  A: 

Try $("td:not(contains('" + selected_text + "'))").parent().remove();

roosteronacid
+1  A: 

At first glance, I'm confused - you're doing an .each() function on every match of ("table#traffic"), but then you're not integrating $(this) anywhere in your .each() function which tells me you could eliminate the .each() loop all together.

As to your question, does the :not selector work with :contains?

$("td:not(:contains('" + selected_text + "'))").parent().remove();
WesleyJohnson
you are correct, the `each` function shown in the Original Post is not helping out here. It could be combined into a single selector instead (but that still doesn't address the problem of "sibling" cells that don't contain the selected text causing the row to be removed regardless, as I noted elsewhere).
Funka
+1  A: 

The remove function can also take an expression as an option.

$("table#traffic tr").remove(":not(:contains('" + selected_text + "')"));

Interestingly enough, the following profiles slightly faster with quite a few rows. I figured the parent() call would eat up more time.

$("table#traffic td:not(:contains('" + selected_text + "'))").parent().remove();

So, I guess you can go with whatever you fine more readable.

ScottE
A: 

I'm surprised no one has mentioned the filter method... From the docs:

filter( expr )
Removes all elements from the set of matched elements that do not match the specified expression(s). This method is used to narrow down the results of a search...

So, perhaps something like this?

$("table#traffic tr")
    .filter(':has(td:contains('" + selected_text + "'))')
    .remove();

Of course, you could still use a combination of not to achieve the same selection (there are many other ways to skin this cat). I just thought I'd mention the filter function, since that is what it is there for.

Finally, I do also want to point out that none of the approaches answered thus far address the very likely situation where you will end up removing rows you don't want to! For example, if a row has multiple cells, you don't want just one of those cells in the row not containing your text to cause the whole row to be removed! Note that in my solution above, filtering is done on the row-level, not the cell-level. (I haven't tested this so please don't jump on me if this doesn't work exactly as is!)

Best of luck!
-Mike

Funka
Actually, the first line of code in ScottE's answer seems like it would not have side-effect I warned against (but his second line of code would).
Funka