拥有此代码
static void Main(string[] args)
{
var test = new List<Tuple<string, int[]>>();
test.Add(new Tuple<string, int[]>("a", new int[] { 1, 4, 7, 8 })); //item 1
test.Add(new Tuple<string, int[]>("a", new int[] { 1, 2, 6, 5 })); //item 2
test.Add(new Tuple<string, int[]>("b", new int[] { 1, 4, 7, 7 })); //item 3
test.Add(new Tuple<string, int[]>("b", new int[] { 1, 2, 3, 4 })); //item 4
test.Add(new Tuple<string, int[]>("a", new int[] { 1, 1, 4, 9 })); //item 5
var result = test.OrderBy(x => x.Item1).ThenBy(x => x.Item2.OrderBy(y => y));
}
返回At least one object must implement IComparable.
不太确定怎么写那个linq所以我会得到这个结果
答案 0 :(得分:2)
我疯狂猜测,因为你没有指定要求(为什么数组会出现在另一个数组之前),但是在收到评论之后,我会提供一个答案&#34;应该&#34;工作(我的想法并没有真正优化):
class ArrayComparer : IComparer<int[]>
{
public int Compare(int[] x, int[] y)
{
for (var i = 0; i < x.Length && i < y.Length; i++)
{
if (x[i] > y[i])
return 1;
if (y[i] > x[i])
return -1;
}
if (y.Length > x.Length)
return -1;
else if (y.Length < x.Length)
return 1;
return 0;
}
}
然后:
var result = test.OrderBy(x => x.Item1)
.ThenBy(x => x.Item2.OrderBy(y => y).ToArray(), new ArrayComparer());
我实际测试了它,这就是结果:
a -> 1,1,4,9 // item 5
a -> 1,2,6,5 // item 2
a -> 1,4,7,8 // item 1
b -> 1,2,3,4 // item 4
b -> 1,4,7,7 // item 3
答案 1 :(得分:2)
自定义IComparer<int[]>
就是您想要的。这是我写它的方式。这将查看各个值,直到找到差异。如果在到达任一数组的末尾之前没有找到差异,那么它将根据数组的长度返回,并使用较短数组较小的度量。
public class ArrayComparer : IComparer<int[]>
{
public int Compare(int[] x, int[] y)
{
for(int i = 0; i < x.Length && i < y.Length; i++)
{
if (x[i] != y[i])
return x[i] - y[i];
}
return x.Length - y.Length;
}
}
使用减法进行比较可以很好地指定IComparer
的返回值。
要使用它,您只需编写
var result = test.OrderBy(x => x.Item1).ThenBy(x => x.Item2.OrderBy(y => y).ToArray(), new ArrayComparer());
答案 2 :(得分:0)
这似乎正在做我想要的事情
var result = test.OrderBy(x => x.Item1)
.ThenBy(x => string.Join(",", x.Item2.OrderBy(y => y)));
并且只能使用相同数量的数字......
答案 3 :(得分:0)
对于我的回答,我创建了一个自定义比较,它比较了Tuple类型和SequenceCompare,通常比较任何类型的数组。我相信这会很快。
这也可以很好地处理不同大小的数组 - 较长的数组可以“更大”。
static void Main(string[] args)
{
var test = new List<Tuple<string, int[]>>();
test.Add(new Tuple<string, int[]>("a", new int[] { 1, 4, 7, 8 })); //item 1
test.Add(new Tuple<string, int[]>("a", new int[] { 1, 2, 6, 5 })); //item 2
test.Add(new Tuple<string, int[]>("a", new int[] { 1, 2, 6 })); //item 2
test.Add(new Tuple<string, int[]>("a", new int[] { 1, 2, 5 })); //item 2
test.Add(new Tuple<string, int[]>("a", new int[] { 1, 6, 5 })); //item 2
test.Add(new Tuple<string, int[]>("a", new int[] { 2, 6, 5 })); //item 2
test.Add(new Tuple<string, int[]>("b", new int[] { 1, 2, 3, 4 })); //item 4
test.Add(new Tuple<string, int[]>("a", new int[] { 1, 1, 4, 9 })); //item 5
var result = test.OrderBy(x => x,new CustomComp()) ;
result.Dump();
}
public class CustomComp : IComparer<Tuple<string, int[]>>
{
public int Compare(Tuple<string, int[]> x,Tuple<string, int[]> y)
{
int strR = string.Compare(x.Item1,y.Item1);
if (strR == 0)
return x.Item2.SequenceCompare(y.Item2);
else
return strR;
}
}
static class Compare
{
public static int SequenceCompare<TSource>(this IEnumerable<TSource> x, IEnumerable<TSource> y)
{
return SequenceCompare(x,y,System.Collections.Generic.Comparer<TSource>.Default);
}
public static int SequenceCompare<TSource>(this IEnumerable<TSource> x, IEnumerable<TSource> y, IComparer<TSource> comparer)
{
if (x == null) throw new ArgumentNullException("x");
if (y == null) throw new ArgumentNullException("y");
using (IEnumerator<TSource> xe = x.GetEnumerator(), ye = y.GetEnumerator())
{
while (true)
{
bool next1 = xe.MoveNext();
bool next2 = ye.MoveNext();
// Are not of same length. longer one >
if (next1 != next2)
{
if (next1 == true) return 1;
return -1;
}
// Both finished -- equal
if (!next1) return 0;
int result = comparer.Compare(xe.Current, ye.Current);
if (result != 0) return result;
}
}
}
}