排序格式化的LINQ查询

ruyhziif  于 2022-12-06  发布在  其他
关注(0)|答案(3)|浏览(177)

给定一个非空字符串stringList序列,其中只包含拉丁字母表中的大写字母。对于所有以相同字母开头的字符串,确定它们的总长度,并获得“S-C”形式的字符串序列,其中S是stringList中以字符C开始的所有字符串的总长度。按总和的数值降序对得到的序列进行排序。对于相等的和值,按C字符代码的升序排列。
这个问题和我之前的一个问题有关。
一个有效的解决方案是:

stringList.GroupBy(x => x[0]).Select(g => $"{g.Sum(x => x.Length)}-{g.Key}");

问题是,对于这个给定的例子,我不知道在哪里添加OrderByDescending()/ThenBy()子句,以便获得正确排序的列表。

0x6upsns

0x6upsns1#

创建一个中间数据结构来存储所需的信息,并将其用于排序,然后生成输出:

stringList
    .GroupBy(x => x[0])
    .Select(g => (Length: g.Sum(x => x.Length), Char: g.Key))
    .OrderByDescending(t => t.Length)
    .ThenBy(t => t.Char)
    .Select(t => $"{t.Length}-{t.Char}");
niwlg2el

niwlg2el2#

你就快成功了。最简单的方法是用你关心的属性创建一个更复杂的对象,用这些属性进行排序,然后在输出中只保留你想要的内容。比如:

stringList
    .GroupBy(x => x[0])
    .Select(g => new {
        Len = g.Sum(x => x.Length),
        Char = g.Key,
        Val = $"{g.Sum(x => x.Length)}-{g.Key}"
    })
    .OrderByDescending(x => Len)
    .ThenBy(x => x.Char)
    .Select(x => x.Val);
qacovj5a

qacovj5a3#

您可以在GroupBy之后添加一个Select,将组转换为包含排序依据的匿名对象。然后,您可以使用OrderByDescendingThenBy进行排序。之后,Select返回所需的格式化字符串:

stringList.GroupBy(x => x[0]) // assuming all strings are non-empty
    .Select(g => new {
        LengthSum = g.Sum(x => x.Length),
        FirstChar = g.Key
    })
    .OrderByDescending(x => x.LengthSum)
    .ThenBy(x => x.FirstChar)
    .Select(x => $"{x.LengthSum}-{x.FirstChar}");

或者,在带有let子句的查询语法中执行此操作,我发现这样更容易阅读:

var query = from str in stringList
    group str by str[0] into g
    let lengthSum = g.Sum(x => x.Length)
    let firstChar = g.Key
    orderby lengthSum descending, firstChar
    select $"{lengthSum}-{firstChar}";

相关问题