CmdrKeene
CmdrKeene

Reputation: 131

jQuery .each() in a nested array

My apologies for the long post but I'll give you the full story. I have a page that lists some products and below each has a little jQueryUI calendar to select a delivery date. I won't get into why, but I have to do what I'm doing with client side scripting.

I'm using jQuery to loop through each product name. For each one, it checks an array of keywords and takes action if the product name is found anywhere in the array.

The end action will be using a call to the associated calendar datepicker and apply a minimum and maximum date to it (that's easy).

What I'm having trouble with now is that I've decided to use a nested array for the product names and the dates you're allowed to choose to have those delivered. So instead of just an array of keywords, I have:

var keywordArray = [
    //product name, start date, end date
    ["foo","2/1/2014","2/13/2014"],
    ["bar","2/7/2014","2/12/2014"]
];

So "foo" can only be delivered between 2/1 and 2/13.


Given this, my inner loop to go through the array needs modified, but I haven't figure out how to do it. It worked great when the array was just a simple array of keywords, but now I need to test the first element of each array in the array of arrays (what a mouthful).

function checkAllowedDates() {
    $("div[id^='delivery_product_name_']").each(function(index) {   //outer loop (each product name)

        str = $("div#delivery_product_name_"+parseInt(index+1)).text(); //gets text inside 'delivery_product_name_1', _2, etc...

        $.each(keywordArray,function(index,value){  //test all array values to see if any are in the product name

            if (str.toLowerCase().indexOf(value) >= 0) {    //contains a keyword
            console.log(str+ " contains the special keyword " + value);
            }
        });
    });
}

I tried using value[0], no dice. I googled/binged how to use nested arrays, and found some great examples and I could probably do it using a normal for loop, but I really wanted to use jQuery on this.

So short form: how do I use $.each() to loop through an array of arrays, and test the 0th index of each inner array (the product name string) to see if it matches the current product name text of my outer loop?

Upvotes: 0

Views: 4191

Answers (4)

Mike Brant
Mike Brant

Reputation: 71384

Why would you not simply use a data structure that is easier to work with like:

var keywordObj = {
    foo: ["2/1/2014","2/13/2014"],
    bar: ["2/7/2014","2/12/2014"]
};

This way you have a key against which you can perform a lookup. This prevents you from needing to do a nested loop at all. You could simply get start/end dates based on your str value like this:

var startDate = keywordObj[str][0];
var endDate = keywordObj[str][1];

You could even have nested object to get specific startDate/endDate properties like

var keywordObj = {
    foo: {
        startDate: "2/1/2014",
        endDate: "2/13/2014"
    },
    bar: {
        startDate: "2/7/2014",
        endDate: "2/12/2014"
    }
};

And then access like:

var selectedItem = keywordObj[str];
console.log(selectedItem.startDate);
console.log(selectedItem.endDate);

To summarize, because you are not structuring you data for easy lookup, you are having to do an unnecessary loop to find the data you are looking for in your data structure. This means your operation has operational complexity of O(n) when it could have O(1). Always think about your data structure and how it needs to be set up to get to the data in best manner.

Upvotes: 1

Spokey
Spokey

Reputation: 10994

You are on the right track but got this line wrong

if (str.toLowerCase().indexOf(value[0]) >= 0) { 

It should actually be the other way around

if (value.indexOf(str.toLowerCase()) >= 0) 

The format is

array.indexOf(searchElement[, fromIndex = 0])

More info and examples here

Upvotes: 0

sai sudhakar
sai sudhakar

Reputation: 204

function checkAllowedDates() {
    $("div[id^='delivery_product_name_']").each(function(index) {   //outer loop (each product name)

        str = $("div#delivery_product_name_"+parseInt(index+1)).text(); //gets text inside 'delivery_product_name_1', _2, etc...

        $.each(keywordArray,function(index,value){  //test all array values to see if any are in the product name

            if (str.toLowerCase().indexOf(value[0]) >= 0) {    //contains a keyword
            console.log(str+ " contains the special keyword " + value[0]);
            }
        });
    });
}

Hope it helps.

Upvotes: 0

Ryo
Ryo

Reputation: 2123

Is this what you want?

$.each(arr, function(){
  console.log("outer loop")
  console.log(this)
  $.each(this, function(){
    console.log("inner loop")
    console.log(this)
  })
})

And output is like

outer loop
[1, 2]
inner loop
Number {[[PrimitiveValue]]: 1}
inner loop
Number {[[PrimitiveValue]]: 2}
outer loop
[3, 4]
inner loop
Number {[[PrimitiveValue]]: 3}
inner loop
Number {[[PrimitiveValue]]: 4}

Upvotes: 0

Related Questions