markilfin
markilfin

Reputation: 83

sorting array by predefined number

Let's say I have multidimensional array

var arr = [{
    "id": "1",
    "firstname": "SUSAN",
    "dezibel": "91"
}, {
    "id": "2",
    "firstname": "JOHNNY",
    "dezibel": "74"
}, {
    "id": "3",
    "firstname": "ANDREA",
    "dezibel": "67"
}];

How can I sort it by "dezibel" but not ascending or descending, but closest to a giving number? For example,

var num = 78;

so target value is 78. and final sorting must be: 74, 67, 91.

Upvotes: 0

Views: 86

Answers (6)

halfbit
halfbit

Reputation: 3939

I would just add a distance and then sort it ...

num=78
for e in arr
    e.dist=Math.abs(e.dezibel - num)
arr.sort (l,r) =>
    if l.dist > r.dist then 1 else -1

delete the dist after

but put in one line is ok, too

    arr.sort (l,r) =>
        if Math.abs(l.dezibel - num) > Math.abs(r.dezibel - num) then 1 else -1

Upvotes: 0

Pabs123
Pabs123

Reputation: 3435

Write a sort function which calculates the distance to your number:

arr.sort(function(a, b){
    return Math.abs(num-a) - Math.abs(num-b);
});

Use this to sort the dezibel properties in your array. It will calculate the distance between each of them and num. It will then select the smaller of the two distances, and continue in this manner to sort the whole array.

Upvotes: 2

Lew
Lew

Reputation: 1278

You can use the array sort function for this:

arr.sort(function(a, b) {
   return num - 1 * a.dezibel + num - 1 * b.dezibel
})

Upvotes: 0

apsillers
apsillers

Reputation: 115950

.sort optionally takes a function. The function takes 2 values at a time, and compares them:

  • If the first value should sort higher than the second, the function should return a positive number.
  • If the first value should sort lower than the second, the function should return a negative number.
  • If the values are equal, the function should returns 0.

So, if you wanted to sort by dezibel in ascending order, you could do

arr.sort(function(a,b){
    return a.dezibel- b.dezibel;
});

However, you want to sort by dezibel's distance from some number. To find the magnitude of the difference from 78 and the dezibel value, take the absolute value of the difference:

Math.abs(78 - a.dezibel)

Now, if we want to sort based on that value for each object, we can take the difference of that Math.abs call for both a and b:

arr.sort(function(a,b){
    return Math.abs(78 - a.dezibel) - Math.abs(78 - b.dezibel);
});

Upvotes: 0

Nina Scholz
Nina Scholz

Reputation: 386654

Just sort by the absolute difference.

var arr = [{ "id": "1", "firstname": "SUSAN", "dezibel": "91" }, { "id": "2", "firstname": "JOHNNY", "dezibel": "74" }, { "id": "3", "firstname": "ANDREA", "dezibel": "67" }],
    num = 78;

arr.sort(function (a, b) {
    return Math.abs(a.dezibel - num) - Math.abs(b.dezibel - num);
});
document.write('<pre>' + JSON.stringify(arr, 0, 4) + '</pre>');

Upvotes: 1

Thriggle
Thriggle

Reputation: 7059

You'll need to use a custom sort function that compares the absolute difference of each object's dezibel attribute from 78.

var arr = [{
    "id": "1",
    "firstname": "SUSAN",
    "dezibel": "91"
}, {
    "id": "2",
    "firstname": "JOHNNY",
    "dezibel": "74"
}, {
    "id": "3",
    "firstname": "ANDREA",
    "dezibel": "67"
}];

num = 78;

arr.sort(
  function(first,second){
    var a = Math.abs(num - (+first.dezibel));
    var b = Math.abs(num - (+second.dezibel));
    return a - b;
  });

alert(JSON.stringify(arr));

Upvotes: 2

Related Questions