Reputation: 87
I have the following array:
[
0 [product_id, title, description]
1 [1234, apple, this is just apple]
2 [2345, pineapple, this is not just apple]
]
This array is long and product_id's can vary by a lot.
I need to select an element based on it's product_id
and update it's title
and description
.
Is there a way to do it without a for
loop (such as for -> if product_id = id -> do something
), since I will end up with n^2?
Thank you for your time.
Upvotes: 0
Views: 70
Reputation: 17334
For an array there is no other way but to loop through it all. You should consider changing your datamodel into a JSON then it will become much easier.
In your example
var products = [
0 [product_id, title, description]
1 [1234, apple, this is just apple]
2 [2345, pineapple, this is not just apple]
]
becomes
var products = {
product_id: [product_id, title, description],
1234: [1234, apple, this is just apple],
2345: [2345, pineapple, this is not just apple]
}
Now you can simply say
var select_1234 = products[1234];
to get the product of 1234.
If you must stick with the array and you need to find products multiple times, consider doing a transform at the beginning of your app to change it into json. As such you have indexed your data and now you can again call
products[1234]
EDIT
Alternatively, you can create json data to link to your array for example
var productsIndex = {
product_id: 0,
1234: 1,
2345: 2
}
This links to the position of the array so now you can call
var find = productsIndex[1234];
var select_1234 = products[find]; //This is the original array.
As an extra, consider using async transformations to transform the data so it does not freeze up any UI. This can be done using a recursive setTimeout with 0 seconds
var products = {
product_id: [product_id, title, description],
1234: [1234, apple, this is just apple],
2345: [2345, pineapple, this is not just apple]
}
var productsIndex = {}
function recursiveTransform(val){
setTimeout(function(){
productsIndex[products[val].[0]] = val; //products[val].[0] is the product id of each array element
if (val != products.length -1) recursiveTransform(val+1);
}, 0)
}
recursiveTransform(0);
By doing this, you will not freeze up your ui or any other operation that might need to be run during the process
Upvotes: 1
Reputation: 3387
There's no way to lookup like you want. You'll need to create a map. That map can either replace your initial array in your data, if it makes sense, or you can just generate a lookup map that you refer to later.
Luckily if you set fooarray[0] = bar;foomap['uuid'] = bar;
, you can update bar via either data structure eg fooarray[0][1] = 'new title'
or foomap['uuid'][1] = 'new title'
and it will update in both structures, because it's passed by reference.
edit building on @YangLi:
var products = {
product_id: [product_id, title, description],
1234: [1234, apple, this is just apple],
2345: [2345, pineapple, this is not just apple]
}
var productsIndex = {}
function recursiveTransform(val){
setTimeout(function(){
productsIndex[products[val].[0]] = products[val];
if (val != products.length -1) recursiveTransform(val+1);
}, 0)
}
recursiveTransform(0);
Upvotes: 0
Reputation: 19475
Use Array.prototype.find
or Array.prototype.findIndex
:
[
[2439, 'title', 'description'],
[1234, 'apple', 'this is just apple'],
[2345, 'pineapple', 'this is not just apple']
].findIndex(function(a){return a[0] == 1234}); // returns 1
[
[2439, 'title', 'description'],
[1234, 'apple', 'this is just apple'],
[2345, 'pineapple', 'this is not just apple']
].find(function(a){return a[0] == 1234}); // returns [1234, 'apple', 'this is just apple']
I’d recommend to simply use a polyfill as well. See the links: they offer polyfills for both so that Chrome and IE can support this as well.
Upvotes: 0