简体   繁体   中英

C# 2D integer array assignment and sorting

I am trying to work with a 2-D array of ints but I have some problems. What i want to do is something like this:

int[,] values = new int[Apples,1]; //Apples = say, 50

What I want to end up with is something like this:

values={ {393,0},{120,1},{9133,2},{75,3},...}; but the 393 , 120 , etc. are values generated in a for loop. That is to say, I cannot initialize the array by assigning it like { {xx},{yy}} , etc. So I want to do something like

for (int i = 0; i<Oranges; i++) {

 values[i,0]={functionCall(),i};
}

where functionCall is prototyped like int functionCall(){...}

but that assignment values[i,0] doesn't work. After this assignment process has completed, I need to sort the array by the first column, so I would get a new array valuesSorted , like this:

valuesSorted={ {75,3},{120,1},{393,0},{9133,2},...} 

so when I iterated over valuesSorted I would get data in that order.

Any ideas how I would do this?

First off let's address your specific problems. The array size should be two, not one; a multidimensional array with one dimension sized to one doesn't make much sense.

int[,] values = new int[50,2]; 

Next, how do you initialize this array in a loop?

for (int i = 0; i<Oranges; i++)
  values[i,0]={functionCall(),i};

This is illegal because the { } syntax can only be used in an array initializer. Instead you mean to say:

for (int i = 0; i < 50; i++)
{
  values[i,0]= functionCall();
  values[i,1]= i;
}

Next, how do you sort the array?

You don't. Multidimensional arrays are hard to sort and there are few tools for doing so. You'd have to write your own sort algorithm to do it in place.

Since that is the goal and we are now frustrated, we should take a step back and reconsider whether a 2-d array is the correct data structure. It isn't. Here's the right way to solve your problem:

struct Pair<T>
{
  public T First { get; private set; }
  public T Second { get; private set; }
  public Pair(T first, T second) : this()
  {
    First = first;
    Second = second;
  }
}
...
static IEnumerable<Pair<int>> Pairs()
{
  int i = 0;
  while(true)
  {
    yield return new Pair<int>(functionCall(), i);
    i = i + 1;
  }
}
...
List<Pair<int>> pairs = 
  Pairs()
    .Take(50)
    .OrderBy(p=>p.First)
    .ToList();

And now we have a sorted list of fifty pairs of ints, which is what you wanted. Moreover, it is extremely clear from the code that we have a sorted list of fifty pairs of ints.

Here is an alternative solution which uses the "select with index" feature that I like a bit better:

static IEnumerable<int> Values()
{
  while(true)
    yield return functionCall();
}
...
List<Pair<int>> pairs = 
  Values()
    .Take(50)
    .Select((item, index)=>new Pair<int>(item, index))
    .OrderBy(p=>p.First)
    .ToList();

When you use data structures that represent the shape of your data accurately and use sequence operators on sequences, life gets easier.

I think you are attempting to keep the original order here in the 2nd column, but it can be done also with a Dictionary<int, int> and SortedList<int,int>

Try this:

class Program
{
    static Random rnd=new Random();

    static int functionCall()
    {
        return rnd.Next(1, 1000);
    }
    static void Main(string[] args)
    {
        var original=new Dictionary<int,int>(10);
        for(int i=0; i<10; i++)
        {
            original.Add(functionCall(), i);
        }
        // original:
        //
        // [646, 0]
        // [130, 1]
        // [622, 2]
        // [454, 3]
        // ...
        // [658, 9]

        var sorted=new SortedList<int, int>(original);

        // sorted:
        //
        // [ 90, 5]
        // [130, 1]
        // [404, 7]
        // [454, 3]
        // ...
        // [756, 8]
    }
}

Note the Random() was added to simulated your functionCall() .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM