35

I have an array which looks like this :

selected_products[0]=["r1","7up",61,"Albertsons"]
selected_products[1]=["r3", "Arrowhead",78,"Arrowhead "]
selected_products[2]=["r8", "Betty Crocker Cake Mix (Variety)",109,"Arrowhead "]
...

how can I search for an item in this array according to the first entry in each item (r1,r2,..) the array is huge I am looking for a fast an effective way to get results from this array I used the JQuery function jQuery.inArray but it couldn't find any thing in my array , I used it this way :

alert($.inArray(["r1","7up",61,"Albertsons"],selected_products))// it returns -1
alert($.inArray("r1",selected_products))//this also returns -1
Evan Lévesque
  • 3,115
  • 7
  • 40
  • 61

6 Answers6

58

If you want it to be fast, you'll want a for loop so that you can break the loop when the match is found.

var result;
for( var i = 0, len = selected_products.length; i < len; i++ ) {
    if( selected_products[i][0] === 'r1' ) {
        result = selected_products[i];
        break;
    }
}

Of course this assumes there's only one match.


If there's more than one, then you could use $.grep if you want jQuery:

var result = $.grep(selected_products, function(v,i) {
    return v[0] === 'r1';
});

This will give you a new Array that is a subset of the matched items.


In a similar manner, you could use Array.prototype.filter, if you only support modern JavaScript environments.

var result = selected_products.filter(function(v,i) {
    return v[0] === 'r1';
});

One other solution would be to create an object where the keys are the rn items. This should give you a very fast lookup table.

var r_table = {};
for( var i = 0, len = selected_products.length; i < len; i++ ) {
    r_table[selected_products[i][0]] = selected_products[i];
}

Then do your lookups like this:

r_table.r4;

Again this assumes that there are no duplicate rn items.

  • @AymanJitan: Well, a breaking `for` loop will be much faster than what you had. But I just added another solution at the bottom that creates an object so you can simply look up each item by `rn` key. I assume that you don't have duplicates in the list. –  Jan 10 '12 at 19:49
  • If you only wanted the index, then in the last solution change `r_table[selected_products[i][0]] = selected_products[i];` to `r_table[selected_products[i][0]] = i;` –  Jan 10 '12 at 19:52
  • @AymanJitan I noticed your comment that says that you want to get the index, you need to return the `i` for this – ajax333221 Jan 10 '12 at 20:06
  • 1
    @ajax333221 yes I know , I get it from this example , thanks you for your note – Evan Lévesque Jan 10 '12 at 20:18
  • Which one of the above solutions would be the absolute fastest? Is the for loop faster? Or is it faster to create an object as you show at the bottom and access that way? – garek007 Feb 27 '23 at 21:42
3

Just to pick up @am not i am's great input. Here is a live example. He solved it. I just wanted to give an example that it works. Hope it helps. This puts the values found from the selected value in 2 input fields.

http://jsfiddle.net/asle/ZZ78j/2/

$(document).ready(function () {
var liste = [];
liste[0] = ["First Name", "12345678", "first.name@testdomain.no"];
liste[1] = ["Second Name", "20505050", "second.nametestdomain.no"];
liste[2] = ["", "", ""];
$("#selger").change(function () {
    var valg = ($(this).val());
    var telefon;
    var epost;
    for (var i = 0, len = liste.length; i < len; i++) {
        if (liste[i][0] === valg) {
            telefon = liste[i][1];
            epost = liste[i][2];
            $("#tel").val(telefon);
            $("#epost").val(epost);
            break;
        }
    }
});

});
Asle
  • 767
  • 2
  • 8
  • 22
3

So you are trying to find the index of the matched result?, well that changes the things a little bit:

var index=-1;

for(var i = 0, len = selected_products.length; i < len; i++){
    if(selected_products[i][0] === "r1"){
        index = i;
        break;
    }
}
if(index > -1){
    alert(selected_products[index].join(","));//"r1,7up,61,Albertsons"
}

Note: This will return the first result matched, if you want to get an array containing a list of all indexes:

var results=[];

for(var i = 0, len = selected_products.length; i < len; i++){
    if(selected_products[i][0] === "r1"){
        results.push(i);
    }
}

You can then call (for example) the last 'r1' matched like this selected_products[results[results.length-1]].join(",");

ajax333221
  • 11,436
  • 16
  • 61
  • 95
  • I forgot to put `if(results.length > 0)` on my last example. But I will leave it this way, since it was just an example of how to call it – ajax333221 Jan 10 '12 at 20:29
1

You might wanna consider not doing these things in Javascript but in a server sided language (PHP/Java/.NET). In this way you:

  • Won't have problems with browser incapabilities (Mostly IE errors)
  • Shorter Javascript code and therefore faster to load.
  • Your site also works with Javascript turned off.

An example how to do this in PHP:

<?php 
function search($array, $key, $value) 
{ 
    $results = array(); 

    if (is_array($array)) 
    { 
        if (isset($array[$key]) && $array[$key] == $value) 
            $results[] = $array; 

        foreach ($array as $subarray) 
            $results = array_merge($results, search($subarray, $key, $value)); 
    } 

    return $results; 
} 
?>
bicycle
  • 8,315
  • 9
  • 52
  • 72
1

Try this,

// returns the index of inner array, if val matches in any array
function findIn2dArray(arr_2d, val){
    var indexArr = $.map(arr_2d, function(arr, i) {
            if($.inArray(val, arr) != -1) {
                return 1;
            }

            return -1;
    });

    return indexArr.indexOf(1);
}


function test(){
    alert(findIn2dArray(selected_products, 'r8'));
}
rahool
  • 629
  • 4
  • 6
0

You may create index object { r1: 1, r2: 2,..., < search key >: < element index >, ...} and use it for searching.

Ilya
  • 1,349
  • 11
  • 16