如果我们想以特殊形式对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 = [{swim,3,woman},{baseball,13,man},{volleyball,12,man},{soccer,12,man}]
答案 0 :(得分:3)
您有一个大字符串数组,其中包含您的所有播放器详细信息。 这不是最佳解决方案。
创建包含所有属性的播放器对象并将其放入数组中。
然后您可以创建自定义排序。
玩家对象:
public class Player {
public string Type { get; set; }
public string Gender { get; set; }
public int AmountOfPlayers { get; set; }
public int Order { get; set; }
}
创建Player对象的数组列表:
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);
答案 1 :(得分:3)
其他答案为创建一个保存数据的类提出了一个很好的观点,但没有它就可以完成:
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();
答案 2 :(得分:2)
While I would suggest the Object oriented approach as illustrated by others. However just in case due to some reservations you cannot do that then this will work.
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;
}
答案 3 :(得分:1)
您可以尝试这种方式。首先从初始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)
代码中进行更改。与使用OrderBy
的{{1}}相比,这是排序的稳定版本。如果您想要将多个分拣机链接在一起,请检查以下响应:
Sort List of Dictionary using IComparer instead of OrderBy
同时使用QuickSort
代替Sort
将确保排序相同的内存,而不是像OrderBy
答案 4 :(得分:1)
从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
数组中某类运动的索引。未知类型的运动最后一次。
答案 5 :(得分:1)
This is not any sort actually but still if you want to process this data you can use following approach which is not good approach though.
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];
}
Use objects,collections and lambda / LINQ for efficient solution and I guess all of the above answers follow the better approach.