3

I am trying to sort an array of objects by comparing it with another object. The final array needs to show selected objects on top and rest beneath that.

Although, I am getting desired output. Just wanted to know if I can optimise it further.

let myArray = [
    { Name: 'Name 1', id: 1111 },
    { Name: 'Name 2', id: 2222 },
    { Name: 'Name 3', id: 3333 },
    { Name: 'Name 4', id: 4444 },
    { Name: 'Name 5', id: 5555 },
    { Name: 'Name 6', id: 6666 }]

let selected = { 1111: 'some value 1', 4444: 'some value 2' }

sortBySelected = (data) => {
    var keys = Object.keys(selected);
    return data.filter((obj) => {
        if (keys.find((key) => {
            return key === String(obj.id);
        })) {
            return true;
        }
        return false;
    });
}

sortByNotSelected = (data) => {
    var keys = Object.keys(selected);
    return data.filter((obj) => {
        if (keys.find((key) => {
            return key === String(obj.id);
        })) {
            return false;
        }
        return true;
    });
}

sort = (data) => {
    data1 = sortBySelected(data);
    data2 = sortByNotSelected(data);
    return data1.concat(data2);
}


console.log(sort(myArray));
3
  • 1
    working code: codereview.stackexchange.com broken code: stackoverflow.com Commented Feb 14, 2018 at 9:39
  • Does the selected and not selected items also need to be sorted wrt each other? Commented Feb 14, 2018 at 9:41
  • what is the wanted order of the top items? the object's order is with keys like integers ordered by value. Commented Feb 14, 2018 at 9:47

3 Answers 3

3

You could use the delta of the check with in operator.

var array = [{ Name: 'Name 1', id: 1111 }, { Name: 'Name 2', id: 2222 }, { Name: 'Name 3', id: 3333 }, { Name: 'Name 4', id: 4444 }, { Name: 'Name 5', id: 5555 }, { Name: 'Name 6', id: 6666 }],
    selected = { 1111: 'some value 1', 4444: 'some value 2' };
    
array.sort((a, b) => (b.id in selected) - (a.id in selected));

console.log(array);
.as-console-wrapper { max-height: 100% !important; top: 0; }

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

1 Comment

You always have the most clever answers <3
1

Use Array.sort for sorting.

myArray.sort(function(a, b) {
  var aSelected = selected[a.id] !== undefined;
  var bSelected = selected[b.id] !== undefined;
  if (aSelected && bSelected === false) {
    // a goes before b
    return -1;
  } else if (aSelected === false && bSelected) {
    // a goes after b
    return 1;
  } else {
    // a and b are considered equal...
    // let the sort function decide the actual position
    return 0;
  }
});

Comments

0

Calling both sortBySelected and sortByNotSelected makes the javascript loop two times over the array, using Array.sort is more elegante but does not seems to be less costy.

I made a little stackblitz example to do some testing : https://stackblitz.com/edit/stackoverflow-48783794

sort function is the initial suggested function, sort2 is a function looping 1 time instead of 2, sort3 using Array.sort.

The result is the same, sort2 seems to be more efficient (link to the result image below) :

enter image description here

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.