2

I have the following array:

var objs = [ 
    { id: 'X82ns', name: 'james', presence: 'online'     },
    { id: '8YSHJ',    name: 'mary', presence: 'offline'   },
    { id: '7XHSK', name: 'rene', presence: 'online' }
];

I want to sort the array so it returns a new array by 'presence': 'online' users displaying first before offline items.

So if sorted, it should return something like this:

var objs = [ 
    { id: 'X82ns', name: 'james', presence: 'online' },
    { id: '7XHSK', name: 'rene', presence: 'online' },
    { id: '8YSHJ',    name: 'mary', presence: 'offline' }
];

Something like this:

const newArray = objs.sort((a, b) => {
      if (a.presence === 'online') {
        return 1;
      } else if (b.presence === 'offline') {
        return -1;
      } else {
        return 0;
      }
    })

return newArray;
}

What is the right way to get the expected result?

Mihai Alexandru-Ionut
  • 47,092
  • 13
  • 101
  • 128
Ericky
  • 654
  • 6
  • 15

10 Answers10

6

You can use localeCompare method.

var objs = [ { id: 'X82ns', name: 'james', presence: 'online' }, { id: '8YSHJ', name: 'mary', presence: 'offline' }, { id: '7XHSK', name: 'rene', presence: 'online' } ];

objs.sort((a,b) => b.presence.localeCompare(a.presence));
console.log(objs);

Don't forget that the sort() method sorts the elements of an array in place so you do not need to use const newArray = objs.sort....

Mihai Alexandru-Ionut
  • 47,092
  • 13
  • 101
  • 128
1

Use sort function with condition of a.presence < b.presence because of online is bigger than offline (f and n)

var objs = [ 
    { id: 'X82ns', name: 'james', presence: 'online'     },
    { id: '8YSHJ',    name: 'mary', presence: 'offline'   },
    { id: '7XHSK', name: 'rene', presence: 'online' }
];

objs.sort(function(a, b) {
  return a.presence < b.presence;
});

console.log(objs);
Saeed
  • 5,413
  • 3
  • 26
  • 40
1

You could simply compare the String with >, = and <

let objs = [ 
    { id: 'X82ns', name: 'james', presence: 'online'     },
    { id: '8YSHJ',    name: 'mary', presence: 'offline'   },
    { id: '7XHSK', name: 'rene', presence: 'online' }
];

let res = objs.sort((a,b) => a.presence > b.presence ? -1 : a.presence == b.presence ? 0 : 1);
console.log(res);
Zenoo
  • 12,670
  • 4
  • 45
  • 69
1

let objArr = [ 
    { id: 'X82ns', name: 'james', presence: 'online'     },
    { id: '8YSHJ',    name: 'mary', presence: 'offline'   },
    { id: '7XHSK', name: 'rene', presence: 'online' }
];

let onlineArr = objArr.filter(x=>x.presence === 'online')
let offlineArr = objArr.filter(x=>x.presence === 'offline')
console.log([...onlineArr, ...offlineArr])

In terms of readability, you can split them into two array and using array destructuring to join them at last

Isaac
  • 12,042
  • 16
  • 52
  • 116
1

You could take an object with the order as values and sort by it. This allowes to use a default value for unknow values.

var array = [{ id: 'X82ns', name: 'james', presence: 'online' }, { id: '8YSHJ', name: 'mary', presence: 'offline' }, { id: '7XHSK', name: 'rene', presence: 'online' }],
    order = { online: 1, offline: 2, default: Infinity };
    
array.sort((a, b) => (order[a.presence] || order.default) - (order[b.presence] || order.default));

console.log(array);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Nina Scholz
  • 376,160
  • 25
  • 347
  • 392
1

Use the > sign to get online first and offline at the end. You can also create a separate function sortFn so this logic can be reused for multiple arrays.

var objs = [ 
    { id: 'X82ns', name: 'james', presence: 'online'     },
    { id: '8YSHJ',    name: 'mary', presence: 'offline'   },
    { id: '7XHSK', name: 'rene', presence: 'online' }
];

function sortFn(a, b){
  return b.presence > a.presence;
}
objs.sort(sortFn);
console.log(objs);
Ankit Agarwal
  • 30,378
  • 5
  • 37
  • 62
1

You need to actually compare the items, and if they are now the same, then check for presence

var objs = [ 
    { id: 'X82ns', name: 'james', presence: 'online'     },
    { id: '8YSHJ',    name: 'mary', presence: 'offline'   },
    { id: '7XHSK', name: 'rene', presence: 'online' }
];

const newArray = objs.sort((a, b) => {
      if (a.presence !== b.presence) {
        return a.presence === "online" ? -1 : 1;
      }
      return 0;
});


console.log(newArray);
Lorenz Merdian
  • 722
  • 3
  • 14
1

Try this:

const newArray = objs.sort((a, b) => {
      if (a.presence === 'online' && b.presence === 'offline') {
        return 1;
      } else if (b.presence === 'online' && a.presence === 'offline') {
        return -1;
      } else {
        return 0;
      }
    })

return newArray;
}
Hasan Fathi
  • 5,610
  • 4
  • 42
  • 60
0

Try This:

var objs = [ 
    { id: 'X82ns', name: 'james', presence: 'online'     },
    { id: '8YSHJ',    name: 'mary', presence: 'offline'   },
    { id: '7XHSK', name: 'rene', presence: 'online' }
];

var statusOrder = ["online", "offline"];

objs = objs.sort(function(a, b) { 
     return statusOrder.indexOf(a.presence) - statusOrder.indexOf(b.presence);
 });

Even shorter with ECMAScript6:

objs = objs.sort((a, b) => statusOrder.indexOf(a.presence) - statusOrder.indexOf(b.presence));

Answer taken from Faly's answer to another post.

Sean Wilson
  • 23
  • 1
  • 5
0

@Oj Obasi, try the below code.

It uses map() method defined on arrays.

    var objs = [ 
        { id: 'X82ns', name: 'james', presence: 'online' },
        { id: '8YSHJ',    name: 'mary', presence: 'offline' },
        { id: '7XHSK', name: 'rene', presence: 'online' }
    ];

    /* Pretty printing objs array*/
    console.log(JSON.stringify(objs, null, 4))  // Before modification (sorting)
    /*
    [
        {
            "id": "X82ns",
            "name": "james",
            "presence": "online"
        },
        {
            "id": "8YSHJ",
            "name": "mary",
            "presence": "offline"
        },
        {
            "id": "7XHSK",
            "name": "rene",
            "presence": "online"
        }
    ]
    */

    objs.map((item, index) => { 
     if(item.presence === 'online') { // online, add to front then remove this item from its current position
      objs.splice(0, 0, item) // add at front
     } else { // offline, push at end then remove this item from its current position
      objs.splice(objs.length, 1, item) // push at end 
     }
     objs.splice(index, 1) // remove
    })

    /* Pretty printing objs array */
    console.log(JSON.stringify(objs, null, 4))  // After modification (sorting)
    /*
    [
        {
            "id": "X82ns",
            "name": "james",
            "presence": "online"
        },
        {
            "id": "7XHSK",
            "name": "rene",
            "presence": "online"
        },
        {
            "id": "8YSHJ",
            "name": "mary",
            "presence": "offline"
        }
    ]
    */
hygull
  • 8,464
  • 2
  • 43
  • 52