I'm trying to sorte an object array by distance. Each object has a x and y coordinate and I want to sort the array so I have the next index is the closest point to index - 1
To do that, I created the following functions:
function compare(a, b) {
dist_yy = (b.bounds.y) - (a.bounds.y);
dist_xx = (b.bounds.x) - (a.bounds.x);
dist = Math.sqrt(dist_yy*dist_yy + dist_xx*dist_xx);
console.log("distance " + dist)
return dist;
}
function sort_overlays(currOverlays) {
sorted_overlays = currOverlays.sort(compare);
currOverlays.forEach(element => {
console.log(element);
});
return sort_overlays;
}
However, it does not seem to work, since I was inspecting the final array (with 700+ points) and some look out of order.
Am I applying the compare function correctly?
kind regards
No, you are not applying your compare function appropriately. A comparer function f(a,b) is meant to return:
A negative number: sort a to an index lower than b
Zero: don't sort
A positive number: sort a to an index higher than b
You are returning a distance, which is meaningless from a comparer perspective.
Reference:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort
Related
I'm trying to solve some 'hackerrank.com' coding challenges.
I'm stuck on this one:
You will be given an array of integers arr and a single integer k. You must create an array arr' of length k from elements of arr such that its unfairness is minimized.
Unfairness is defined as max(arr') - min(arr')
The function should return the minimum possible unfairness
My code works fine for the majority of test cases. However, in three of those test cases - the ones where the size of arr and k is particularly huge - fail due to an excession of the given time limit.
How can I optimize the performance of my code?
Thanks in advance
function maxMin(k, arr) {
// create array to push unfairness values to
var unfairnesses = [];
// sort given array in ascending order
arr.sort(function(a, b) {
return a - b;
});
// loop over sorted array
for(var i = 0; i < arr.length - k + 1; i++) {
// get array with the length of k at position i
var tempArr = arr.slice(i, i + k);
// determine Max and Min of the sliced array
var tempArrMax = Math.max(...tempArr);
var tempArrMin = Math.min(...tempArr);
// get unfairness of the sliced array
var thisUnfairness = tempArrMax - tempArrMin;
// push sliced-array-unfairness to unfairnesses array
unfairnesses.push(thisUnfairness);
}
// return minimal value of unfairnesses array
return Math.min(...unfairnesses);
}
The two first steps could be:
Your array is sorted. Thus there's no need to use Math.max and Math.min - the first element of a slice is the smallest, the last is the largest.
When you eliminate Math.max and Math.min calls, you can remove Array.prototype.slice call. Then you're left with a sort and a single pass over the array.
To sort the array you're already looping one time over the whole thing.
Then you're looping another time to figure out which one is max and which one is the minimum.
You're looping twice as you can only loop once if you do:
function minMax(array) {
const safeArray = array ?? []
// No max or min as array is empty
if(safeArray.length === 0)
return [undefined, undefined]
let max: number = Number.MIN_SAFE_INTEGER
let min: number = Number.MAX_SAFE_INTEGER
for(let item of safeArray) {
max = Math.max(item, max)
min = Math.min(item, min)
}
return [max, min]
}
I have an array like this
arr1 = ["P2.13","P1.13","P4.13","P3.13", "P2.14","P2.14","P1.14","P4.14","P1.15","P2.15","P3.15","P4.15"];
How can I sort the array by the number after the dot FIRST, from 13 to 15, then sort by the number after "P" from 1 to 4? Finaly I want an array like this
arr2 = ["P1.13","P2.13","P3.13","P4.13","P1.14","P2.14","P3.14","P4.14","P1.15","P2.15","P3.15","P4.15"];
Appreciate!!
Pass a function into sort. The following will work for the precise test case provided, but would need to be modified if the input is more general.
arr1.sort(function(a, b) {
return a.slice(-2) - b.slice(-2) || a[1] - b[1];
});
Note that this will mutate arr1.
For programs that include many functional programming I choose Underscore library.
You can directly call sortBy function based on multiple attributes with a hacky trick by joining them. Here is the code:
var sortedArray = _.sortBy(arr1, function(item) {
var nums = item.split('.');
return [nums[1], nums[0]].join("_");
});
However, you can still use Javascript sort function to sort list with customized compare function. Here is the code:
arr1.sort(function(x, y) {
var numsX = x.split('.');
var numsY = y.split('.');
if (numsX[1] !== numsY[1]) {
return compare(numsX[1], numsY[1]); // compare the number after dot first
}
return compare(numsX[0], numsY[0]); // compare the number before dot after
});
// General comparison function for convenience
function compare(x, y) {
if (x === y) {
return 0;
}
return x > y ? 1 : -1;
}
Check two examples on fiddle
Underscore sort vs
Javscript sort
This is my new account, I don't have reputation to post more than 2 links. You can search underscore library.
Thanks.
I have an array of objects, whose elements as displayed using ng-repeat from AngularJS. Each object has a priority_int integer value, and I know that I can sort the array is descending order with:
array.sort(function(a,b){
return b.priority_int - a.priority_int;
}
Currently, I'm adding everything to the array, before sorting by priority_int in descending order, and then displaying with ng-repeat.
Out of curiousity, how can I sort every time I push an object into the array?
Resorting the array each time you add an element will cost a heavy runtime penalty, especially since some default array.sort implementations have an O(n^2) runtime for a nearly-sorted array.
Instead, use binary search to insert new elements into the correct position in the sorted array.
Check this related answer for more help:
Efficient way to insert a number into a sorted array of numbers?
The easiest way to do this would be to first find the index of where the new element should be placed. Then, you should add the element there.
var addToReverseSortedArray = function (arr, item) {
// our function to find the index of an element
// (or where it should be placed)
var search = function (a, i) {
var low = 0, high = a.length - 1;
while (low <= high) {
var mid = (low + high) >> 1;
if (a[mid] > i) low = mid + 1;
else if (a[mid] < i) high = mid - 1;
else return mid;
}
return low;
}
// Array.splice can actually splice 0 items
// here, we splice 0 items at index search(arr, item)
// and add `item`
arr.splice(search(arr, item), 0, item);
return arr;
}
Mind you, the above function relies on an array in reverse sorted order.
Examples:
addToReverseSortedArray([5,4,3], 6); // [6,5,4,3]
addToReverseSortedArray([1,0,0,0], 10); // [10,1,0,0,0]
I have a list of numbers and I need to find the n smallest of them.
This is what I have so far, but I'm sure it must be possible to do it faster and cleaner (maybe without having to sort the entire list first?):
var list = [56,34,27,4,78,12,89,1002,45,33,87,90];
var results = [];
var sorted_list = list.slice(); // fastest way to duplicate array
sorted_list.sort(function (a, b) {
return a - b;
});
for (var i = 0; i < n; i++) {
// do stuff with sorted_list[i] and list
// push the result to results
}
return results;
I think if you use a Min Heap to solve this problem, it will be faster. By that I mean
Form a min heap from an array.
Take out the min element and heapify.(This step you will repeat, depending upon how many items you want)
Sorting algorithm will take O(N*logN) time, while Min Heap creation(step 1) will take O(N) time and O(logN){average} will be time taken by the second step.
Note that: Heap is useful when the number of items you needs is less than N. If you repeat the step 2 N times, the total time comes out to O(N*logN) itself same as sorting.
Array.min = function( array ){
return Math.min.apply( Math, array );
};
Source: http://ejohn.org/blog/fast-javascript-maxmin/
Thanks for the clarification. For n elements use:
Array.min = function( array, n ){
return array.sort(function(a, b){return a-b}).slice(0, n);
};
Without sorting it can be done in this way.
Basically the idea is that everytime in each iteration we will push the smallest number in an array.
and will remove that number from the main array
Suppose we have an array of length 12
a=[-11,2,1,5,0,9,-8,6,-10,0,12,4];
and we have to find 4 smallest number
we can find using this function(am is the result array)
function findmin(a) {
var item=Math.min.apply(Math, a);
var index= a.indexOf(item);
am.push(item);
a.splice(index, 1);
if(am.length<n)
findmin(a)
}
Now suppose we have to find 9 smallest number from the array
we can find(12-9=3) max number and remove it from the given array and then that will be our
result.
function findmax(a) {
var item=Math.max.apply(Math, a);
var index= a.indexOf(item);
am.push(item);
a.splice(index, 1);
if(a.length>n)
findmax(a)
}
Here I think the complexity is nm where m is no. of element to be found and n is total no. of element.If I am not wrong.
Actually i am weak in finding complexity.So please suggest if any improvement can be done.
SEE DEMO HERE
I'm trying to sort this object by the score value so I can populate a highscores table. Found this method of sorting which works lovely for sorting smallest to highest with a - in the formula, but when I try and reverse it with a + it doesn't work. I'm confused..
JS:
scores = [
{"n":"Arne", "score":700},
{"n":"Bertil", "score":430},
{"n":"Carl", "score":901},
{"n":"David", "score":30},
{"n":"Eric", "score":23},
{"n":"Frida", "score":118},
{"n":"Greg", "score":221},
{"n":"Hulk", "score":543}
];
scores.sort(function(a, b) {
return a.score + b.score;
});
//add rows to table from scores object
var t = document.getElementById('table');
for (var j in scores) {
var r = document.createElement('tr')
r.innerHTML = '<td><span></span></td><td>'+scores[j].n+'</td><td>'+scores[j].s+'</td>'
t.appendChild(r);
}
You mention that you're trying to reverse the sort, which originally involved subtraction.
Thus I think it's fair to assume that your original sort was like this...
scores.sort(function(a, b) {
return a.score - b.score;
});
If you want to sort in the opposite direction, simply reverse the order of the subtraction:
scores.sort(function(a, b) {
return b.score - a.score;
});
your sort function should return positive , 0 , or negative values
you probably trying to add some numbers there which is a mistake.
try here :
http://jsbin.com/icojaz/edit#javascript,html
it sorts by score.
According to http://www.w3schools.com/jsref/jsref_sort.asp you can see that you just reverse the input parameters like this: return a.score - b.score;