1

I have array of objects and my requirement was to group users by status (online users should come first) while sort grouped users by name. I am able to achieve result but here I am using lodash concat function separately. Can anyone help to use it along with chain function?

Code:

  import _ from 'lodash';

  const { online = [], offline = [] } = _.chain(users)
    .sortBy([(e) => _.toLower(e.name)])
    .groupBy((e) => e.status)
    .value();
  const result = _.concat(online, offline);
  console.log('grouped users sorted by name => ', result);

Input:

let users = [
    {
        'name': 'C',
        'status': 'online'
    },
    {
        'name': 'd',
        'status': 'online'
    },
    {
        'name': 'a',
        'status': 'offline'
    },
    {
        'name': 'b',
        'status': 'online'
    },
    {
        'name': 'f',
        'status': 'offline'
    },
    {
        'name': 'e',
        'status': 'offline'
    }
];

Output:

[
    {
        'name': 'b',
        'status': 'online'
    },
    {
        'name': 'C',
        'status': 'online'
    },
    {
        'name': 'd',
        'status': 'online'
    },
    {
        'name': 'a',
        'status': 'offline'
    },
    {
        'name': 'e',
        'status': 'offline'
    },
    {
        'name': 'f',
        'status': 'offline'
    }
]

Thanks

3 Answers 3

1

You can do this easily without lodash too.

You can use a customized sort function when calling the sort() function of an array. Create a sort string including a 0 for online users and a 1 for offline users followed by the name. Then use this sort string in the comparison.

let users = [{
    'name': 'C',
    'status': 'online'
  },
  {
    'name': 'd',
    'status': 'online'
  },
  {
    'name': 'a',
    'status': 'offline'
  },
  {
    'name': 'b',
    'status': 'online'
  },
  {
    'name': 'f',
    'status': 'offline'
  },
  {
    'name': 'e',
    'status': 'offline'
  }
];

users.sort((a, b) => {
  let sortStringA = (a.status.toUpperCase() == 'ONLINE' ? 0 : 1) + a.name.toUpperCase();
  let sortStringB = (b.status.toUpperCase() == 'ONLINE' ? 0 : 1) + b.name.toUpperCase();
  if (sortStringA < sortStringB) {
    return -1;
  }
  if (sortStringA > sortStringB) {
    return 1;
  }
  return 0;
});

console.log(users);

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

1 Comment

Thanks @MarkBaijens simple and straightforward solution.
1

You can use reduce,filter & sort. Create a separate array and add the status in order you want the final array to be be. Then inside the reduce callback use filter to get the elements of that status and use sort to sort the elements in order of name

let sortStatus = ['online', 'offline'];
let users = [{
    name: 'C',
    status: 'online'
  },
  {
    name: 'd',
    status: 'online'
  },
  {
    name: 'a',
    status: 'offline'
  },
  {
    name: 'b',
    status: 'online'
  }
];
let data = sortStatus.reduce((acc, curr) => {
  acc.push(
    ...users
    .filter(item => item.status === curr)
    .sort((a, b) => a.name.localeCompare(b.name))
  );
  return acc;
}, []);
console.log(data);

1 Comment

Thanks @brk I was looking for solution using lodash or with plain js (but simple solution)
1

If You can correct input:

let users = [
    {
        name: 'C',
        status: 'online'
    },
    {
        name: 'd',
        status: 'online'
    },
    {
       name: 'a',
        status: 'offline'
    },
    {
        name: 'b',
        status: 'online'
    },
    {
        name: 'f',
        status: 'offline'
    },
    {
        name: 'e',
        status: 'offline'
    }
];

const sorted = users.sort((a, b) => {
if (a.name.toLowerCase() < b.name.toLowerCase()) {
    return a.status.toLowerCase() < b.status.toLowerCase() ? 1 : -1;
  }
   return b.status.toLowerCase() < a.status.toLowerCase() ? -1 : 1;;

})
console.log(sorted )

1 Comment

Thanks @Nikola Pavicevic

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.