3

What is the best structure solution for find element(Object) in Object Array by value of one of the keys.

For example we have array:

var someArray = 
[
 {id:17, color:'black', width:50},
 {id:34, color:'red', width:150},
 {id:49, color:'gree', width:10}
]

and we need to find an Object with id-key = 34.

And each time we will have to do the loop to find the object. I thought about restructuring and having object instead of array like so:

 var someObject = 
 {
 17: {id:17, color:'black', width:50},
 34: {id:34, color:'red', width:150},
 49: {id:49, color:'gree', width:10}
 }

Now we can do it in one step someObject[34], BUT what if we want to keep the order?

Thanks in advance.

asked Feb 7, 2014 at 16:28
2
  • What do you mean with "keep the order"? An object has no "order" among its properties. Sure, you can get the keys with Object.keys or for (... in ... ), but IIRC you simply can't rely on its order, as it can be browser-specific. Commented Feb 7, 2014 at 16:34
  • 1
    What I've done before is I've created a class that has the array of objects and I also give the class a dictionary. When I search for the object I need I save the object's identifier and row/index in the dictionary. When I try to find the object in this class I first look at the dictionary - if it has a record for the ID I check to see if its index is pointing to the same object and not different/null/out of range. If not, then I search and save the identifier/row in the dictionary. Works pretty well and is easy to implement. Commented Feb 7, 2014 at 16:41

3 Answers 3

2

I thought about restructuring and having object instead of array

Yes, that's fine.

BUT what if we want to keep the order?

I tend to use an extra array that contains the keys in the correct order, like

var order = [17, 34, 47];

To loop them, you'd use

for (var i=0; i<order.length; i++) {
 ... someObject[order[i]] ...
}
answered Feb 8, 2014 at 13:38
Sign up to request clarification or add additional context in comments.

Comments

1

You should prefix the id to avoid naming collisions, like this:

var database = 
{
 'row_17' : {id:17, color:'black', width:50},
 'row_34' : {id:34, color:'red', width:150},
 'row_49' : {id:49, color:'gree', width:10}
};

At this point you can query the object with this code:

function retrieve(database, id)
{
 id = 'row_' + id;
 if (!database.hasOwnProperty(id))
 {
 return null;
 }
 return database[id];
}

The persist function would be:

function persist(database, obj)
{
 database['row_' + obj['id']] = obj;
}

If you need to keep an order you have first to understand what order you are talking about.

Of the id? Of the insert? Or of an arbitrary property?

There are solutions to all of these by filtering (extracting the items and putting them into a separate array that would be the query result or with additional fields or structures.

EDIT: how to keep insertion order

You'll need an array that keeps track of order:

database._ordered = [];

On insert, push the item there, too:

database._ordered.push(obj);

Now you can pick single items by key and all items ordered. There is no way you can have an order in an object, it's simply the wrong tool for that.

The row_ prefix is recommended to avoid naming collisions with methods and whatnot. An object should hold properties and methods, if you use it like a dictionary at least prevent interference by prefixing.

answered Feb 7, 2014 at 16:40

2 Comments

You don't have an order per se, the order depends on how you list the items. If you want to keep the insertion order you can take my solution and adapt it easily.
sorry, but I don't think that it is a solution. I've already described this case. You only wrapped it into functions and add "row_" prefix (dunno why)
1

You can use function findWhere from underscore library, in your case it would be like this:

_.findWhere(someArray, {id: 34})
answered Jul 30, 2014 at 16:08

Comments

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.