我有一个像这样的列表:
List<Users>
我有一本字典:
Dictionary<int, User> userIdToUsers
其中int
是User.Id
属性值。
现在我想订购:
因此,如果用户在词典中,它应该在顶部,然后按创建日期排序。
这是可能的,还是我必须创建一个组合User对象和布尔标志的中间对象?
答案 0 :(得分:4)
var sorted = source.OrderBy(x => !userIdToUsers.ContainsKey(x.Id))
.ThenBy(x => x.Created)
.ToList();
如果您需要以相反的顺序,请在OrderBy
/ OrderByDescending
和ThenBy
/ ThenByDescending
之间进行更改。
答案 1 :(得分:1)
编辑:基于澄清OP需求的评论,以下LINQ查询应该执行所请求的内容。
IEnumerable<User> ordered = source.OrderBy(x => !userIdToUsers.ContainsKey(x.Id)).ThenBy(y => y.Created);
如果您希望ordered
成为List<User>
,则只需更改声明并在查询中添加ToList()
。
答案 2 :(得分:1)
您还可以使用Comparison<T>
闭包进行就地排序:
List<User> users = GetUserList() ;
Dictionary<int,User> userIdToUsers = GetUserIdMap() ;
users.Sort( (x,y) =>
{
// handle null values gracefully. NULL always compares low.
if ( x == null && y == null ) return 0 ;
else if ( x == null && y != null ) return -1 ;
else if ( x != null && y == null ) return +1 ;
// at this point, x and y are both non-null,
// we need to check whether x and y are mapped in the dictionary
// if one is mapped and the other is not,
// the mapped instance collates *before* the unmapped instance.
bool xMapped = userIdToUsers.Contains(x.Id) ;
bool yMapped = userIdToUsers.Contains(y.Id) ;
if ( xMapped && !yMapped ) return -1 ;
else if ( !xMapped && yMapped ) return +1 ;
// We now know that both are either mapped or unmapped and so collate equal
// we break the tie by comparing the date/time created property.
return x.DateTimeCreated.CompareTo(y.DateTimeCreated) ;
});