2

I am new to Angular and currently working on a Angular 5 application. I have a requirement to get the next or previous item from a dictionary(model) for next and previous navigation to get the route. I looked into multiple articles and came up with the following method. Let me know whether any other efficient and reliable way to do this. I need to also make sure its sorted by value to make sure it retains the same order between server(api) and client. This will be an important method for our application navigation so I want to make sure there is no browser compatibility issues, no drawbacks and its reliable. Worst case I can go with regular switch case statement, it will be ugly with multiple conditions but will be OK. Let me know your thoughts. Thanks in advance

var dict = {
  "name3": 12,
  "name1": 5,
  "name2": 8
};

var items = sortProperties(dict);
//console.log(items);

var getItem = function(key, i) {

var index = 0;
var stop = true;
for (var j = 0; j < items.length; j++) {  
   
        if (items[j][0] == key) {
            index = j;
            break;// Found it
        }
    }    
console.log(index);
if((index + i) > -1 && (index+i) <items.length)
{
  return items[index+i][0];
}
else
{
 return 'empty';
 }  
}


console.log(getItem("name2",-1));
console.log(getItem("name2",+1));



function sortProperties(obj)
{
  // convert object into array
	var sortable=[];
	for(var key in obj)
		if(obj.hasOwnProperty(key))
			sortable.push([key, obj[key]]); // each item is an array in format [key, value]
	
	// sort items by value
	sortable.sort(function(a, b)
	{
	  return a[1]-b[1]; // compare numbers
	});
	return sortable; // array in format [ [ key1, val1 ], [ key2, val2 ], ... ]
}

12
  • 2
    you are better off using an array since JavaScript property order is not guaranteed. If you have an object then convert it to an array. Commented Sep 20, 2018 at 12:43
  • @danday74 does the order in the array remains the same b/w api and client? ie., will it retain the order in the way it was added? Thanks Commented Sep 20, 2018 at 13:04
  • also if the array is always sorted and the distribution isn't too extreme, you can do some kind of optimistic log(n) lookup (like binary search) instead of blindly iterating through the whole thing. Commented Sep 20, 2018 at 13:07
  • yes it will retain order guaranteed - when you .push() your are adding to the end - when you .unshift() you are adding to the beginning Commented Sep 20, 2018 at 13:08
  • to find an object in an array you should be using lodash find like this ... stackoverflow.com/questions/31054021/… ... most people in the JS world use lodash - it provides a load of functions which make array manipulation easy and so on - its the most popular JS lib and npm module Commented Sep 20, 2018 at 13:10

1 Answer 1

3

According to the spec, there is no intrinsic order of properties in objects. While in practice that order is deterministic, it is a bad idea to rely on that.

Sorting the properties every time you want the next or previous one is about as inefficient as it can get without making it worse on purpose. At least use an array to store your (sorted) entries permanently.

If those operations (next and previous) are the main thing you plan to do with your structure and there can be a lot of items in it, you should use a structure that does the operations cheaply: a doubly-linked list.

If you want both that and cheap direct access, you'll have to pay for it somewhere. One solution would be to use an array or Map for cheap direct access, and maintain next and previous properties on all the items in it to also have linked-list behaviour. You'll pay for it every time you mutate the structure, but that may be okay, especially if it doesn't change often.

Sign up to request clarification or add additional context in comments.

5 Comments

Good explanation of the linked list / array
Thanks for the reply. I prefer your suggestion of maintaining a next and previous properties on all items in a dictionary and just do a direct lookup on client. I am planning to store this in a session service so will be reloaded/rebuilt (in web server) only on refresh. Thanks
If you do that, it may be best if you transfer the dictionary in this form: [[name1, {val1, next, prev}], [name2, {val2, next, prev}}], …]. Because you can pass that to the Map constructor. Maps are a bit nicer than raw objects for this kind of usage (for one thing, they are iterables). If everything is computed server-side, the next and prev properties can just be the key of the next and previous item, instead of a reference. So if you have already got an entry item, you'd get the next one with dict.get(item.next)
Oh, and Maps do guarantee that the iteration order is the order that the items were inserted in.
@Touffy thanks. I think I just need [[name1, {next, prev}]. I haven't worked with Map so far. I will look into it. if I am storing prev and next value in the same item then I don't need a id to order by and order should not matter anymore. I can do a look up by key ie., name1. Thanks

Your Answer

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.