LINQ非线性顺序的字符串长度

时间:2014-05-10 21:54:10

标签: c# linq

我试图获取一个有序的字符串列表,这样最长的列表位于列表的两端,最短的位于中间。例如:

A
BB
CCC
DDDD
EEEEE
FFFFFF

将排序为:

FFFFFF
DDDD
BB
A
CCC
EEEEE

编辑:为了澄清,我特意寻找LINQ实现来实现预期的结果,因为我不确定如何使用LINQ进行操作。

3 个答案:

答案 0 :(得分:10)

您可以创建两个有序组,然后命令第一组降序(已完成)和第二组升序:

var strings = new List<string> { 
        "A",
        "BB",
        "CCC",
        "DDDD",
        "EEEEE",
        "FFFFFF"};
var two = strings.OrderByDescending(str => str.Length)
        .Select((str, index) => new { str, index })
        .GroupBy(x => x.index % 2)
        .ToList(); // two groups, ToList to prevent double execution in following query
List<string> ordered = two.First() 
    .Concat(two.Last().OrderBy(x => x.str.Length))
    .Select(x => x.str)
    .ToList();

结果:

[0] "FFFFFF"    string
[1] "DDDD"      string
[2] "BB"        string
[3] "A"         string
[4] "CCC"       string
[5] "EEEEE"     string

答案 1 :(得分:7)

不要问怎么回事...... ^^

list.Sort(); // In case the list is not already sorted.

var length = list.Count;

var result = Enumerable.Range(0, length)
                       .Select(i => length - 1 - 2 * i)
                       .Select(i => list[Math.Abs(i - (i >> 31))])
                       .ToList();

好的,在我忘记它是如何工作之前,你走了。

例如,必须对包含6个项目的列表进行重新排序;最长的字符串在索引5处,是预先排序列表的索引0处的最短字符串。

5 3 1 0 2 4

我们从Enumerable.Range(0, length)屈服

开始
0 1 2 3 4 5

然后我们应用i => length - 1 - 2 * i产生

5 3 1 -1 -3 -5

我们的非负面部分是正确的。现在注意i >> 31是算术左移,并将符号位复制到所有位。因此,非负数产生0而负数产生-1。这反过来意味着减去i >> 31不会改变非负数,而是将1加到负数产生

5 3 1 0 -2 -4

现在我们最终应用Math.Abs()并获取

5 3 1 0 2 4

这是期望的结果。对于奇数长度的列表,它的工作方式类似。

答案 2 :(得分:0)

只是另一个选项,我发现它更易读并易于理解: 你有一个有序的清单:

var strings = new List<string> { 
        "A",
        "BB",
        "CCC",
        "DDDD",
        "EEEEE",
        "FFFFFF"};

创建一个新列表,并简单地替换添加项目的位置::

var new_list = new List<string>();  // This will hold your results
bool start = true;                  // Insert at head or tail

foreach (var s in strings)
{
    if (start)
        new_list.Insert(0,s);
    else        
        new_list.Add(s);

    start = !start;             // Flip the insert location
}

甜蜜而简单:)

至于 Daniel Bruckner 评论,如果您关心哪些字符串首先出现,您还可以将开始条件更改为:

 // This will make sure the longest strings is first
 bool start= strings.Count()%2 == 1;