以特殊样式排序字符串数组

时间:2015-06-26 09:02:51

标签: c# arrays sorting

如果我们想以特殊形式对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}]

6 个答案:

答案 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;
}

DEMO

答案 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.

相关问题