views:

783

answers:

3

I'm looking for a concise way to compare two arrays for any match.

I am using this comparison to apply a particular style to any table cell that has matching content. One array is a static list of content that should be contained in at least one table cell on the page. The other array is being generated by JQuery, and is the text of all table cells.

The reason why I have to compare content to apply style is that the HTML document will semantically change over time, is being generated by different versions of excel (pretty awful looking code), and this script needs to accommodate that. I know that the content I'm looking to apply the style to in this document will never change, so I need to detect all matches for this content to apply styles to them.

So, the code should be something like (in english):

for each table cell, compare cell text to contents of array. If there is any match, apply this css to the table cell.

This is what I have so far (and I know it's wrong):

$(document).ready(function(){


$("a.loader").click(function(event){
     event.preventDefault();
     var fileToLoad = $(this).attr("href");
     var fileType = $(this).text();
     var makes = new Array("ACURA","ALFA ROMEO","AMC","ASTON MARTIN","ASUNA","AUDI","BENTLEY","BMW","BRITISH LEYLAND","BUICK","CADILLAC","CHEVROLET","CHRYSLER","CITROEN","COLT","DACIA","DAEWOO","DELOREAN","DODGE","EAGLE","FERRARI","FIAT","FORD","GEO","GMC","HONDA","HUMMER","HYUNDAI","INFINITI","INNOCENTI","ISUZU","JAGUAR","JEEP","KIA","LADA","LAMBORGHINI","LANCIA","LAND ROVER","LEXUS","LINCOLN","LOTUS","M.G.B.","MASERATI","MAYBACH","MAZDA","MERCEDES BENZ","MERCURY","MG","MINI","MITSUBISHI","MORGAN","NISSAN (Datsun)","OLDSMOBILE","PASSPORT","PEUGEOT","PLYMOUTH","PONTIAC","PORSCHE","RANGE ROVER","RENAULT","ROLLS-ROYCE / BENTLEY","SAAB","SATURN","SCION","SHELBY","SKODA","SMART","SUBARU","SUZUKI","TOYOTA","TRIUMPH","VOLKSWAGEN","VOLVO","YUGO","Acura","Alfa Romeo","Amc","Aston Martin","Asuna","Audi","Bentley","Bmw","British Leyland","Buick","Cadillac","Chevrolet","Chrysler","Citroen","Colt","Dacia","Daewoo","Delorean","Dodge","Eagle","Ferrari","Fiat","Ford","Geo","Gmc","Honda","Hummer","Hyundai","Infiniti","Innocenti","Isuzu","Jaguar","Jeep","Kia","Lada","Lamborghini","Lancia","Land Rover","Lexus","Lincoln","Lotus","M.G.B.","Maserati","Maybach","Mazda","Mercedes Benz","Mercury","Mg","Mini","Mitsubishi","Morgan","Nissan (Datsun)","Oldsmobile","Passport","Peugeot","Plymouth","Pontiac","Porsche","Range Rover","Renault","Rolls-Royce / Bentley","Saab","Saturn","Scion","Shelby","Skoda","Smart","Subaru","Suzuki","Toyota","Triumph","Volkswagen","Volvo","Yugo");
 $("div#carApp").html("<img src='images/loadingAnimation.gif' alt='LOADING...' />");
 $("div#carApp").load(fileToLoad, function(){
  $("#carApp style").children().remove();
  $('#carApp td').removeAttr('style');
 $('#carApp td').removeAttr('class');
 $('#carApp table').removeAttr('class');
 $('#carApp table').removeAttr('style');
 $('#carApp table').removeAttr('width');
 $('#carApp tr').removeAttr('style');
 $('#carApp tr').removeAttr('class');
 $('#carApp col').remove();
 $('#carApp table').width('90%');
 var content = $("#carApp table td");
    jQuery.each(content, function() {
  var textValue = $(this).text();
  if (jQuery.inArray(textValue, makes)==true){
   $(this).css("color","red");
  }
  else{
  }
   });
 });

}); });

Any ideas?

A: 

Have you had a look at $.grep() ?

Finds the elements of an array which satisfy a filter function. The original array is not affected. The filter function will be passed two arguments: the current array item and its index. The filter function must return 'true' to include the item in the result array.

Russ Cam
i did but the examples in jquery documentation weren't very clear to me; do you have any suggestions for other resources?
Sarah Jean
A: 

You're checking $.inArray(...) == true. inArray actually returns an integer with the index of the item in the array (otherwise -1.) So you want to check if it is greater than or equal to 0.

Here's how you can change your each loop.

$('#carApp td').each(function () {
    var cell = $(this);
    if ($.inArray(cell.text(), makes) >= 0) {
        cell.addClass('selected-make');
    }
});

I use a CSS class instead of the style attribute, because it's better practice to put styling in a CSS file rather than in your JavaScript code. Easier to update that way (especially when you want to apply the same style in multiple places in your code.)

Other points worth noting:

  • jQuery selections have the each(...) function as well. So you can do $(...).each(...) instead of jQuery.each($(...), ...)
  • jQuery and $ are the same object as long as you don't have other frameworks that redefine the $ variable. Therefore you can do $.inArray(...) instead of jQuery.inArray(...). It's a matter of taste, though.
Blixt
inArray doesn't return a boolean.
J-P
Yeah I spotted it just after I submitted the post and edited it straight away, you must've loaded the page during the moment I hadn't edited it =P
Blixt
it wasn't working because of the boolean; i changed to != -1 and it works fine.I usually change it to a class too-- and i will be, but I needed to get it to work first so i just put a quick css style change in there for testing.Thanks again!!!
Sarah Jean
Ah, I see. I added a couple of more points that to my answer that I forgot to mention (things I changed from your code.)
Blixt
I was wondering about that! I'm always fishing through the examples in the documentation and things like that are never absolutely clear to me. I thought I could substitute $ for jQuery but the examples all had jQuery.whatever(). Thanks again.
Sarah Jean
A: 

An optimization would be to make makes a hash (aka dictionary):

var makes = { "ACURA": 1,"ALFA ROMEO": 1,"AMC": 1, ...};

Then you don't have to iterate makes every time with inArray.

...
var textValue = $(this).text();
  if (makes[textValue] == 1)
    $(this).css("color","red");
  }
...
bic72