我试图获取一个有序的字符串列表,这样最长的列表位于列表的两端,最短的位于中间。例如:
A
BB
CCC
DDDD
EEEEE
FFFFFF
将排序为:
FFFFFF
DDDD
BB
A
CCC
EEEEE
编辑:为了澄清,我特意寻找LINQ实现来实现预期的结果,因为我不确定如何使用LINQ进行操作。
答案 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;