在C#中按字符串数组的第二个Dimesion排序

时间:2017-11-27 11:37:06

标签: c# arrays sorting multidimensional-array

我们有二维字符串数组,如

"0" => {"John","23"},
"1" => {"Doe","12"},
"2" => {"Maria","41"},
 .......

我们希望对此数组进行排序,如

 "0" => {"Maria","41"},
 "1" => {"John","23"},
 "2" => {"Doe","12"},
     .......

我们的数组代码String[,] kelimedeger = new String[20, 2];

我们希望按kelimedeger[i,1]

订购

2 个答案:

答案 0 :(得分:1)

关于排序

我在这里看到的一个问题是你的第二个“字符串”实际上不是一个字符串,而是一个数字。因此,您实际上有一个名字和年龄的人。

为什么这很重要?

排序取决于数据类型。字符串按字母顺序排序,而数字按数字排序。

考虑以下列表:

1, 2, 17, 11, 100, 20, 34

这可以用多种方式排序

Numerical    Alphabetical
---------    ------------
1            1
2            100
11           11
17           17
20           2
34           20
100          34

鉴于您很可能希望以数字方式排序,您需要将数据存储为int,而不是string

如何存储数据?

这取决于您的用例。如果保证名称是唯一的,那么您可以使用Dictionary<string,int>。否则,我建议您创建一个班级Person并使用ICollection<Person>来存储它们。

作为Dictionary<string, int>

如果保证名称在您的域中是唯一的,则此方法很有用。此外,它只使用内置类型。

namespace DictionaryTest
{
  public class Program
  {
    public static void Main(string[] args)
    {
      //Create a dictionary to store people
      Dictionary<string, int> people = new Dictionary<string, int>();

      //Add some people. Note that this is type-safe
      people.Add("John", 23);
      people.Add("Doe", 12);
      people.Add("Maria", 41);
      //people.Add("John", 55); // <-- This will fail because there is already a John

      //Create queries to ensure correct sorting
      var peopleByName = from p in people
                         orderby p.Key //Our name is the key, the age is the value
                         select new {Name = p.Key, Age = p.Value};

      var peopleByAge = from p in people
                        orderby p.Value
                        select new {Name = p.Key, Age = p.Value};

      var peopleByAgeDescending = from p in people
                                  orderby p.Value descending
                                  select new {Name = p.Key, Age = p.Value};

      //Execute the query and print results
      foreach(var person in peopleByAge)
      {
        Console.WriteLine("Hello, my name is {0} and I am {1} years old", person.Name, person.Age);
      }
    }
  }
}

Try it online!

作为ICollection<Person>

此方法定义了一个类Person,它只包含Name和Age属性,但可以扩展为包含更多信息,方法等。

namespace ClassTest
{
  public class Program
  {
    public static void Main(string[] args)
    {
      //Create a list to store people
      ICollection<Person> people = new List<Person>();

      //Add some people. Note that this is type-safe
      people.Add(new Person(){ Name = "John", Age = 23, FavouriteColour = "Blue" });
      people.Add(new Person(){ Name = "Doe", Age = 12});
      people.Add(new Person(){ Name = "Maria", Age = 41, FavouriteColour = "Purple" });
      people.Add(new Person(){ Name = "John", Age = 55, FavouriteColour = "Gray" }); //<-- You can indeed have two people with the same name

      //Create queries to ensure correct sorting
      var peopleByName = from p in people
                         orderby p.Name
                         select p;

      var peopleByAge = from p in people
                        orderby p.Age
                        select p;

      var peopleByAgeDescending = from p in people
                                  orderby p.Age descending
                                  select p;


      //Execute the query and print results
      foreach(var person in peopleByAge)
      {
        Console.WriteLine("Hello, my name is {0} and I am {1} years old.", person.Name, person.Age);
        if(person.FavouriteColour != null)
        {
          Console.WriteLine("My favourite colour is {0}.", person.FavouriteColour);
        }
        else
        {
          Console.WriteLine("I have no favourite colour.");
        }
        Console.WriteLine(); //Add a new line for better readability
      }
    }
  }

  public class Person
  {
    public string Name { get; set; }
    public int Age { get; set; }
    public string FavouriteColour { get; set; }
  }
}

Try it online!

我个人更喜欢第二种方法,因为它更具扩展性,并且不需要名称的唯一性。它允许您根据需要扩展Person类,并为您提供更多的排序选项。

答案 1 :(得分:0)

要对二维数组进行排序,您需要将每一行转换为一维数组并将其保存在List或类似的内容中。然后,您可以按列对列表进行排序。排序后,您需要将列表转换回二维数组。 这是一种可用于排序的方法:

public static T[,] Sort2DArray<T>(T[,] array, int column, bool ascending = true)
{
    int i = 0;
    List<T[]> items = new List<T[]>();

    int columns = array.GetLength(1);
    int rows = array.GetLength(0);

    T[] obj = new T[columns];
    foreach (var item in array)
    {
        obj[i % columns] = item;
        if ((i + 1) % 2 == 0)
        {
            items.Add(obj);
            obj = new T[columns];
        }

        i++;
    }

    var ordered = ascending ? items.OrderBy(a => a[column]) : items.OrderByDescending(a => a[column]);


    T[,] result = new T[rows, columns];
    for (int r = 0; r < rows; r++)
    {
        var row = ordered.ElementAt(r);
        for (int c = 0; c < columns; c++)
        {
            result[r, c] = row[c];
        }
    }
    return result;
}

您的代码如下所示:

string[,] array =
{
    {"John", "23" },
    {"Doe", "12" },
    {"Maria", "41" },
};

string[,] ordered = Sort2DArray(array, 1);//Sort by column 1 / Age

将二维数组转换为一维数组并返回不是排序值的最佳例程。正如David Stockinger和Tim Schmelter所说,最好的方法是创建一个存储数据的类。