3

I have the following array of unique IDs:

idArray = ["56f4cf96dd2ca7275feaf802",
"56f4cf96dd2ca7275feaf7b7",
"56f4cf96dd2ca7275feaf805",
"56f4cf96dd2ca7275feaf7ac"]

And I have another array of objects:

stories = [{"title": Story2, id = "56f4cf96dd2ca7275feaf7b7"},
{"title": Story4, id = "56f4cf96dd2ca7275feaf7ac"},
{"title": Story1, id = "56f4cf96dd2ca7275feaf802"},
{"title": Story3, id = "56f4cf96dd2ca7275feaf805"}]

How can I sort the second array based on the index of the first array? Preferably using lodash, as the arrays can grow a bit larger.

So far, I have the following to get the indexes from the first array:

var sortArray = _.toPairs(idArray)

[ [ '0', 56f4cf96dd2ca7275feaf802 ],
[ '1', 56f4cf96dd2ca7275feaf7b7 ],
[ '2', 56f4cf96dd2ca7275feaf805 ],
[ '3', 56f4cf96dd2ca7275feaf7ac ] ]

Trying different combinations of _.map() and _.sortBy() I can't seem to properly get the result I want which is:

desiredResult = [{"title": Story1, id = "56f4cf96dd2ca7275feaf802"},
          {"title": Story2, id = "56f4cf96dd2ca7275feaf7b7"},
          {"title": Story3, id = "56f4cf96dd2ca7275feaf805"},
          {"title": Story4, id = "56f4cf96dd2ca7275feaf7ac"}]

3 Answers 3

4

I believe the sort solution is very ineffective especially since you expect the arrays to grow bigger later. Sort is "at best" an O(2n) operation while you have two indexOf operations per cycle another O(2n^2). I propose the following which will outperform the sort method in large arrays.

var stories = [{"title": 'Story2', id : "56f4cf96dd2ca7275feaf7b7"},
{"title": 'Story4', id : "56f4cf96dd2ca7275feaf7ac"},
{"title": 'Story1', id : "56f4cf96dd2ca7275feaf802"},
{"title": 'Story3', id : "56f4cf96dd2ca7275feaf805"}],

    idArray = ["56f4cf96dd2ca7275feaf802",
"56f4cf96dd2ca7275feaf7b7",
"56f4cf96dd2ca7275feaf805",
"56f4cf96dd2ca7275feaf7ac"],

ordered = idArray.reduce((p,c) => p.concat(stories.find(f => f.id == c)) ,[]);

console.log(ordered);

Only O(n^2)

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

Comments

3

This is possible to do without any library using Array.sort()

var stories = [{"title": 'Story2', id : "56f4cf96dd2ca7275feaf7b7"},
{"title": 'Story4', id : "56f4cf96dd2ca7275feaf7ac"},
{"title": 'Story1', id : "56f4cf96dd2ca7275feaf802"},
{"title": 'Story3', id : "56f4cf96dd2ca7275feaf805"}];

var idArray = ["56f4cf96dd2ca7275feaf802",
"56f4cf96dd2ca7275feaf7b7",
"56f4cf96dd2ca7275feaf805",
"56f4cf96dd2ca7275feaf7ac"];

var ordered = stories.sort(function(a, b){
	return idArray.indexOf(a.id) - idArray.indexOf(b.id);
});

ordered.forEach( element =>{ console.log(element) });

3 Comments

Exactly my thought. You beat me to it... Here, have a fiddle: jsfiddle.net/jx3we8q7 ;)
Thank you, great answer. Is it ok to do 'return idArray.indexOf(b.id) - dArray.indexOf(a.id)' to reverse the order? Or should I use reverse() on the resulting array?
I think there's nothing bad to do it.
1

Try this

var idsToIndexes = {};

for (var i = 0; i < idArray.length; i++)
    idsToIndexes[idArray[i]] = i;

stories.sort(function(a, b){return idsToIndexes[a.id] - idsToIndexes[b.id];});

Comments

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.