Ericky
Ericky

Reputation: 664

How to sort array by array field value javascript

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?

Upvotes: 2

Views: 142

Answers (10)

hygull
hygull

Reputation: 8740

@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"
        }
    ]
    */

Upvotes: 0

Hasan Fathi
Hasan Fathi

Reputation: 6106

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;
}

Upvotes: 1

Sean Wilson
Sean Wilson

Reputation: 23

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.

Upvotes: 0

Lorenz Merdian
Lorenz Merdian

Reputation: 752

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);

Upvotes: 1

Ankit Agarwal
Ankit Agarwal

Reputation: 30739

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);

Upvotes: 1

Nina Scholz
Nina Scholz

Reputation: 386654

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; }

Upvotes: 1

Isaac
Isaac

Reputation: 12874

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

Upvotes: 1

Zenoo
Zenoo

Reputation: 12880

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);

Upvotes: 1

Saeed
Saeed

Reputation: 5488

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);

Upvotes: 1

Mihai Alexandru-Ionut
Mihai Alexandru-Ionut

Reputation: 48367

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....

Upvotes: 6

Related Questions