I've done some extensive searching for this so if this is a duplicate please slaughter me :D
我已经做了一些广泛的搜索,所以如果这是重复请宰我:D
I have a List of byte arrays (List) where the arrays are of varying length. I need to sort the list by the array lengths in ascending order then by the bytes in the array (please see example).
我有一个字节数组列表(List),其中数组的长度各不相同。我需要按数组长度按升序排序列表,然后按数组中的字节排序(请参见示例)。
Example:
例:
I want to go from:
我想从:
{0,1,2}
{0,4}
{0,3,2}
{0,1,3}
{0,2,4,6,1}
{0,1,1}
{0,3,4,5}
to:
至:
{0,4}
{0,1,1}
{0,1,2}
{0,1,3}
{0,3,2}
{0,3,4,5}
{0,2,4,6,1}
It's essentially alphabetical order but with a set of numbers instead of characters (arguably the same thing), any ideas?
它基本上是字母顺序,但有一组数字而不是字符(可以说是同一个东西),任何想法?
2 个解决方案
#1
8
The only thing you need to do is implement a IComparer<T>
interface and provide that to the sorting algorithm. In this case the algorithm looks like:
您唯一需要做的就是实现IComparer
public ByteArrayComparer : IComparer<byte[]> {
public int Compare (byte[] ba, byte[] bb) {
int n = ba.Length; //fetch the length of the first array
int ci = n.CompareTo(bb.Length); //compare to the second
if(ci != 0) { //if not equal return the compare result
return ci;
} else { //else elementwise comparer
for(int i = 0; i < n; i++) {
if(ba[i] != bb[i]) { //if not equal element, return compare result
return ba[i].CompareTo(bb[i]);
}
}
return 0; //if all equal, return 0
}
}
}
Next you can use the List<T>.Sort
method:
接下来,您可以使用List
List<byte[]> data = new List<byte[]>();
//add arrays to data
data.Sort(new ByteArrayComparer());
//data is now sorted
The sorting algorithm requires that the comparator is valid, a comparator is valid if it satisfies the three constraints on an ordering relation:
排序算法要求比较器有效,如果比较器满足排序关系的三个约束,则比较器有效:
-
Reflexivity: if an elements is compared with itself, return
0
; - 反身性:如果将元素与自身进行比较,则返回0;
-
Anti-symmetric: If x is smaller than y (return something less than
0
), then y is greater than x (something greater than0
); - 反对称:如果x小于y(返回小于0的值),则y大于x(大于0);
- Transitive: if x is smaller than y and y is smaller than z, then x is smaller than z.
- 传递性:如果x小于y且y小于z,则x小于z。
If the comparer doesn't satisfy that relation, the sorting algorithm will fail to sort correctly, simply because your order makes no sense.
如果比较器不满足该关系,则排序算法将无法正确排序,因为您的顺序没有意义。
#2
1
Why not simply use LINQ
为什么不简单地使用LINQ
MyList = MyList.OrderBy(arr=>arr.Length).ThenBy(arr =>arr.Sum()).ToList();
A working example :
一个工作的例子:
List<int[]> a = new List<int[]>();
int[] t1 = { 0, 4 };
int[] t2 = { 0, 1, 2 };
int[] t3 = { 0, 1, 3 };
int[] t4 = { 0, 2, 4, 6, 1 };
int[] t5 = { 0, 1, 1 };
int[] t6 = { 0, 3, 4, 5 };
a.Add(t1);
a.Add(t2);
a.Add(t3);
a.Add(t4);
a.Add(t5);
a.Add(t6);
a = a.OrderBy(arr=>arr.Length).ThenBy(arr =>arr.Sum()).ToList();
foreach (int[] item in a)
{
foreach (int item2 in item)
{
Console.Write(" "+item2);
}
Console.WriteLine();
}
Sample output :
样本输出:
0 4
0 1
0 1 2
0 1 3
0 3 4 5
0 2 4 6 1
And as pointed out this could fail in scenarios like {3 4 5} , {4 5 3}
正如所指出的那样,{3 4 5},{4 5 3}这样的情况可能会失败
#1
8
The only thing you need to do is implement a IComparer<T>
interface and provide that to the sorting algorithm. In this case the algorithm looks like:
您唯一需要做的就是实现IComparer
public ByteArrayComparer : IComparer<byte[]> {
public int Compare (byte[] ba, byte[] bb) {
int n = ba.Length; //fetch the length of the first array
int ci = n.CompareTo(bb.Length); //compare to the second
if(ci != 0) { //if not equal return the compare result
return ci;
} else { //else elementwise comparer
for(int i = 0; i < n; i++) {
if(ba[i] != bb[i]) { //if not equal element, return compare result
return ba[i].CompareTo(bb[i]);
}
}
return 0; //if all equal, return 0
}
}
}
Next you can use the List<T>.Sort
method:
接下来,您可以使用List
List<byte[]> data = new List<byte[]>();
//add arrays to data
data.Sort(new ByteArrayComparer());
//data is now sorted
The sorting algorithm requires that the comparator is valid, a comparator is valid if it satisfies the three constraints on an ordering relation:
排序算法要求比较器有效,如果比较器满足排序关系的三个约束,则比较器有效:
-
Reflexivity: if an elements is compared with itself, return
0
; - 反身性:如果将元素与自身进行比较,则返回0;
-
Anti-symmetric: If x is smaller than y (return something less than
0
), then y is greater than x (something greater than0
); - 反对称:如果x小于y(返回小于0的值),则y大于x(大于0);
- Transitive: if x is smaller than y and y is smaller than z, then x is smaller than z.
- 传递性:如果x小于y且y小于z,则x小于z。
If the comparer doesn't satisfy that relation, the sorting algorithm will fail to sort correctly, simply because your order makes no sense.
如果比较器不满足该关系,则排序算法将无法正确排序,因为您的顺序没有意义。
#2
1
Why not simply use LINQ
为什么不简单地使用LINQ
MyList = MyList.OrderBy(arr=>arr.Length).ThenBy(arr =>arr.Sum()).ToList();
A working example :
一个工作的例子:
List<int[]> a = new List<int[]>();
int[] t1 = { 0, 4 };
int[] t2 = { 0, 1, 2 };
int[] t3 = { 0, 1, 3 };
int[] t4 = { 0, 2, 4, 6, 1 };
int[] t5 = { 0, 1, 1 };
int[] t6 = { 0, 3, 4, 5 };
a.Add(t1);
a.Add(t2);
a.Add(t3);
a.Add(t4);
a.Add(t5);
a.Add(t6);
a = a.OrderBy(arr=>arr.Length).ThenBy(arr =>arr.Sum()).ToList();
foreach (int[] item in a)
{
foreach (int item2 in item)
{
Console.Write(" "+item2);
}
Console.WriteLine();
}
Sample output :
样本输出:
0 4
0 1
0 1 2
0 1 3
0 3 4 5
0 2 4 6 1
And as pointed out this could fail in scenarios like {3 4 5} , {4 5 3}
正如所指出的那样,{3 4 5},{4 5 3}这样的情况可能会失败