I have an array of a class that is representing a user and another array of a class that is representing pinned items (currently only user ids). Here are the classes:
public class User
{
public int UserId { get; set; }
public bool Pinned { get; set; }
public User(int userId, bool pinned)
{
UserId = userId;
Pinned = pinned;
}
}
public class PinnedItem
{
public int UserId { get; set; }
public PinnedItem(int userId)
{
UserId = userId;
}
}
All user ids of pinned users are saved in a specific order (order of pinned items) and I want to order the array of users so that pinned users are on top and those pinned users follow the order of pinned items array. So for example, if I have an array of users like:
var users = []{ new User(1, true), new User(2, false), new User(3, true) }
and a pinned items array that looks like this:
var pinnedItems = new [] { new PinnedItem(3), new PinnedItem(1) }
then I want the resulting array to look like this:
[ {3, true}, {1, true}, {2, false} ]
Any kind of help will be very much appreciated. Also if there is anything unclear in the question, I am sorry and will edit it accordingly if need be.
CodePudding user response:
It's a bit scruffy, but something like this will do it:
var joined =
users
.GroupJoin(pinnedItems, u => u.UserId, p => p.UserId, (u, p) => new { u.UserId, Pinned = p.Any() })
.OrderByDescending(r => r.Pinned)
.ThenByDescending(r => r.UserId)
.ToList();
You can tune the projections and sorting to get it just how you want it.
CodePudding user response:
Im sure there are alot of ways to do this, I have alot of LINQ left to learn but the following should get you started;
// First, get the users that are mentioned by a PinnedItem
var pinnedUsers = pinnedItems.Select(x => users.FirstOrDefault(y => y.UserId == x.UserId));
// Get all the users that are not mentioned in a PinnedItem
var unpinnedUsers = users.Except(pinnedUsers);
// Combine both
var both = pinnedUsers.Concat(unpinnedUsers);