以特殊样式对字符串数组进行排序
本文关键字:数组 排序 字符串 样式 | 更新日期: 2023-09-27 17:59:56
如果我们想以特殊形式对string Array
进行排序,我们需要做什么?
例如,我们有这个:
players = new string[12] {"soccer","12","man","swim","3","woman","volleyball","12","man","baseball","13","man"};
现在我们想按这种形式对Array
进行排序:(这只是我的愿望顺序,没有任何逻辑(
sort = new string[4] {"swim","baseball","volleyball","soccer"}
最后有:
out = [{游泳,3,女人},{棒球,13,男人},{排球,12,男人},{足球,12,男人}]
其他答案很好地说明了如何创建一个类来保存数据,但可以在没有它的情况下完成:
var ordered = Enumerable.Range(0, players.Length / 3)
.Select(i => new string[] { players[i*3], players[i*3+1], players[i*3+2] })
.OrderBy(a => Array.IndexOf(sort, a[0]))
.ToArray();
如果球员数组中有排序数组中不存在的运动,则可以将其过滤掉。
var ordered = (from i in Enumerable.Range(0, players.Length / 3)
let index = Array.IndexOf(sort, players[i*3])
where index >= 0
select new string[] { players[i*3], players[i*3+1], players[i*3+2] }
).OrderBy(a => Array.IndexOf(sort, a[0])).ToArray();
你有一个大的字符串数组,其中包含所有玩家的详细信息。这不是最好的解决方案。
创建包含所有属性的玩家对象并将其放在数组中。
然后,您可以创建自定义排序。
播放器对象:
public class Player {
public string Type { get; set; }
public string Gender { get; set; }
public int AmountOfPlayers { get; set; }
public int Order { get; set; }
}
创建玩家对象的数组列表:
List<Player> list = new List<Player>();
list.Add(new Player() { Type = "swim", Gender = "women", AmountOfPlayers = 3, Order = 1 });
list.Add(new Player() { Type = "soccer", Gender = "men", AmountOfPlayers = 12, Order = 4 });
list.Add(new Player() { Type = "volleyball", Gender = "men", AmountOfPlayers = 12, Order = 3 });
list.Add(new Player() { Type = "baseball", Gender = "men", AmountOfPlayers = 13, Order = 2 });
排序:
var sortedList = list.OrderBy(c => c.Order);
虽然我建议其他人说明的面向对象的方法。但是,以防万一由于某些保留而无法这样做,那么这将起作用。
string[] players = new string[15] {"soccer","12","man","swim","3","woman","volleyball","12","man","baseball","13","man"
,"chess","18","man"};
string[] sort = new string[4] {"swim","baseball","volleyball","soccer"};
string[] playersSorted= new string[sort.Length*3];
int destStartIndex = 0;
foreach(string str in sort)
{
int sourceStartIndex = Array.IndexOf(players,str);
Array.Copy(players, sourceStartIndex, playersSorted, destStartIndex, 3);
destStartIndex += 3;
}
演示
你可以试试这种方式。首先从初始string[]
创建一个类,它可以以如下所示的格式表示所有值:
Class Sport
{
public string Name {get; set;}
public int Number {get; set;}
public string Gender {get; set;}
}
将集合作为List<Sport> sportList
后,现在您需要创建自定义IComparer
来执行必要的排序:
class SportSorter : IComparer<Sport>
{
public int Compare(Sport x, Sport y )
{
int retVal = 0;
retVal = string.Compare(x.Name,y.Name);
return retVal;
}
}
现在,您只需可以使用 SportSorter
的实例进行调用
SportSorter ss = new SportSorter();
sportList.Sort(ss);
请注意,现在我正在使用Name
属性进行排序,可以在CustomSorter (IComparer)
代码中进行更改。与使用 QuickSort
的 OrderBy
相比,这是一个稳定的排序版本。如果您想将多个分拣机在不同方向上链接在一起,请检查以下响应:
使用 IComparer 而不是 OrderBy 对字典列表进行排序
此外,使用 Sort
代替 OrderBy
将确保对相同的内存进行排序,而不是像 OrderBy
那样创建新列表
从 Mivaweb 复制的代码:
public class Player {
public string Type { get; set; }
public string Gender { get; set; }
public int AmountOfPlayers { get; set; }
}
然后
List<Player> list = new List<Player>();
list.Add(new Player() { Type = "swim", Gender = "women", AmountOfPlayers = 3 });
我的代码:
public static readonly string[] Order = new string[4] {"swim","baseball","volleyball","soccer"};
public static int OrderOf(string str)
{
int ix = Array.IndexOf(Order, str);
if (ix == -1)
{
ix = int.MaxValue;
}
return ix;
}
然后排序:
list.Sort((p, q) => OrderOf(p.Type).CompareTo(OrderOf(q.Type)));
list.Sort()
是"到位"的,所以它直接改变了list
。请注意,如果存在与 lsit 中的运动不同的运动,它们将排在排序列表的第一位。
OrderOf
使用Array.IndexOf
在Order
数组中查找某种运动类型的索引。未知类型的运动排在最后。
这实际上不是任何种类,但如果您想处理这些数据,您可以使用以下方法,但这不是好方法。
string[,] outArray = new string[sort.Length, 3];
for (int i = 0; i < sort.Length; i++)
{
int pos = Array.IndexOf(players, sort[i]);
outArray[i, 0] = players[pos];
outArray[i, 1] = players[pos + 1];
outArray[i, 2] = players[pos + 2];
}
使用对象,集合和lambda/LINQ进行有效的解决方案,我想上述所有答案都遵循更好的方法。