-2

I have two JavaScript objects:

var list = [];
list.push({'xid':'12345@kvm.dooth.com'});
list.push({'xid':'6789@kvm.dooth.com'});
list.push({'xid':'1357@kvm.dooth.com'});
list.push({'xid':'2468@kvm.dooth.com'});

var recent = [];
recent.push({'12345@kvm.dooth.com':3});
recent.push({'1357@kvm.dooth.com':1});
recent.push({'2468@kvm.dooth.com':2});

I need to sort list object using recent object. I am expecting an output like:

[{
  'xid': '1357@kvm.dooth.com'
}, {
  'xid': '2468@kvm.dooth.com'
}, {
  'xid': '12345@kvm.dooth.com'
}, {
  'xid': '6789@kvm.dooth.com'
}]
ssilas777
  • 9,672
  • 4
  • 45
  • 68
Anish Chandran
  • 427
  • 1
  • 5
  • 19

3 Answers3

0
const sortedList = list.sort((a, b) => {
  // The ids
  const aXid = a.xid
  const bXid = b.xid

  // The positions
  const [aPos] = recent.filter(e => e.hasOwnProperty(aXid)).map(e => e[aXid])
  const [bPos] = recent.filter(e => e.hasOwnProperty(bXid)).map(e => e[bXid])

  // Compare like usual numbers
  return (aPos || Number.MAX_SAFE_INTEGER) - (bPos || Number.MAX_SAFE_INTEGER)
})
Balázs Édes
  • 13,452
  • 6
  • 54
  • 89
0

I use Array.prototype.sort() and Array.prototype.find():

var list = [];
list.push({'xid':'12345@kvm.dooth.com'});
list.push({'xid':'6789@kvm.dooth.com'});
list.push({'xid':'1357@kvm.dooth.com'});
list.push({'xid':'2468@kvm.dooth.com'});

var recent = [];
recent.push({'12345@kvm.dooth.com':3});
recent.push({'1357@kvm.dooth.com':1});
recent.push({'2468@kvm.dooth.com':2});

function sort(list, recent){
  list.sort(function (a, b) {
    a = getEmailValue(recent, a["xid"]);
    b = getEmailValue(recent, b["xid"]);
    return (a !== undefined) ? (a - b) : 1;
  });
}

function getEmailValue(recent, email) {
  var elem = recent.find(function (e) {
    return e[email] !== undefined;
  });

  return elem && elem[email];
}

sort(list, recent);
console.log(list);

sort() works by taking two elements from the array - a and b. It sorts them based on the return value of a compare function. If that function returns a positive number, a is put after b, if it's negative, a is before b, else they are unchanged.

In this:

return (a !== undefined) ? (a - b) : 1;

If a is undefined (getEmailValue() has returned nothing), 1 is returned to sort it in the back. In your example, emails with no value in recent are at the bottom of the list.

This:

return elem && elem[email];

Will return elem[email] if elem is not undefined, else it will return undefined. It's a way to prevent accessing the email property of something that is not an object. For more info, check here.

Logical AND (&&) - expr1 && expr2 - Returns expr1 if it can be converted to false; otherwise, returns expr2. Thus, when used with Boolean values, && returns true if both operands are true; otherwise, returns false.

dodov
  • 5,206
  • 3
  • 34
  • 65
0

You can first create one object or hash table from recent array and then you can use sort() to sort by that object. First you need to sort by values that exists in recent from list or that are != undefined and then by values in recent object.

var list = [];
list.push({'xid':'12345@kvm.dooth.com'});
list.push( {'xid':'6789@kvm.dooth.com'});
list.push( {'xid':'1357@kvm.dooth.com'});
list.push({'xid':'2468@kvm.dooth.com'});

var recent = [];
recent.push({'12345@kvm.dooth.com':3});
recent.push({'1357@kvm.dooth.com':1});
recent.push({'2468@kvm.dooth.com':2});

var hash = recent.reduce(function(r, e) {
  for(var i in e) r[i] = e[i]
  return r
}, {})

var result = list.sort(function(a, b) {
  return ((hash[b.xid] != undefined) - (hash[a.xid] != undefined)) || 
    (hash[a.xid] - hash[b.xid])
})

console.log(result)
Nenad Vracar
  • 118,580
  • 15
  • 151
  • 176