我有这样的名单,我想点这个
然后按字母顺序排列
我有这个linq查询
var groups = profileModel.Groups.
OrderByDescending(i => i.FullName.ToLower().Contains("ab")).
ThenByDescending(i => i.FullName.ToLower().Contains("cd")).
ThenByDescending(i => i.FullName.ToLower().Contains("ef"));
我应该如何扩展这个?我必须使用分组吗?
答案 0 :(得分:0)
您似乎想要这个,然后无需使用GroupBy
:
var groupOrders = new List<string> { "ab", "cd", "ef" };
var resultList = profileModel.Groups
.Select(x => new { ModelGroup = x, First2Letter = x.FullName.Substring(Math.Min(2, x.FullName.Length)) })
.Select(x => new
{
x.ModelGroup,
x.First2Letter,
Index = groupOrders.FindIndex(s => s.Equals(x.First2Letter, StringComparison.OrdinalIgnoreCase))
})
.OrderByDescending(x => x.Index >= 0) // first all known groups
.ThenBy(x => x.Index)
.ThenBy(x => x.ModelGroup.FullName)
.Select(x => x.ModelGroup)
.ToList();
答案 1 :(得分:0)
如果我正确地解决了问题,这将根据它们包含的内容订购商品。也应该在EF工作。
var orderItems = from item in profileModel.Groups
let name = item.FullName.ToLower()
orderby (name.Contains("ab") ? 1 : 0) + (name.Contains("cd") ? 0.1 : 0) + (name.Contains("ef") ? 0.01 : 0) descending
select item;
EDIT 重新阅读问题后,这可能是正确的解决方案
var orderItems = from item in profileModel.Groups
let name = item.FullName.ToLower()
let order = name.Contains("ab") ? 3 : name.Contains("cd") ? 2 : name.Contains("ef") ? 1 : 0
orderby order descending, item.FullName
select item;
答案 2 :(得分:0)
对于自定义排序,您可以为每个比较条件分配一个值,OrderByDescending将按此顺序排序。像这样......
lstModel = profileModel.Groups.OrderByDescending(m => m.FullName.ToLower().Contains("ab") ? 3 :
m.FullName.ToLower().Contains("cd") ? 2 :
m.FullName.ToLower().Contains("ef") ? 1 : 0).ToList();
答案 3 :(得分:0)
如果您可能要测试更多或不同的level1值,则可能需要通用版本。
使用方便的扩展方法FirstOrDefault
,该方法采用默认值返回
public static T FirstOrDefault<T>(this IEnumerable<T> src, Func<T, bool> test, T defval) => src.Where(aT => test(aT)).DefaultIfEmpty(defval).First();
您可以按顺序创建第一级值的数组,然后先按字母顺序排序,然后按字母顺序排序:
var level1 = new[] { "ab", "cd", "ef" };
var ans = groups.OrderBy(i => level1.Select((op, n) => (op, n))
.FirstOrDefault(opn => i.FullName.Contains(opn.op),
(op: String.Empty, n: level1.Length)).n)
.ThenBy(i => i.FullName);