Reputation: 131
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
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
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
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
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