2

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?

3
  • 3
    Your data doesn't fit your description - are you sure you don't have new int[Apples, 2] instead? And do you have to use a multi-dimensional array here instead of a single-dimensional array of some appropriate type? (Are you really representing pairs of numbers?) Commented Oct 2, 2013 at 15:14
  • You should use a Tuple<int, int>[] Commented Oct 2, 2013 at 15:16
  • 2
    Jon is right; a multidimensional array where one of the dimensions is of size one doesn't make much sense. If your intention is to represent an array of pairs, consider defining a Pair<T> struct and making an array of pairs of integers. Commented Oct 2, 2013 at 15:19

2 Answers 2

4

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.

Sign up to request clarification or add additional context in comments.

1 Comment

A third alternate is to use Enumerable.Range(0, 50) and then select out the pairs from that. (In the event you wanted to avoid iterator blocks and infinite sequences, as it can take a bit of time to get used to both of those concepts.)
0

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().

3 Comments

This assumes that the results of the function call have no duplicates, and also note that SortedList is going to have pretty poor performance here, compared to the alternatives. It's a generally poor data structure in general performance wise; it's rarely the best solution to any given problem.
The OP has no requirements as far as performance goes. As far as unique keys, the OP did not specify, but you are correct that it would fail if they keys clash.
For my problem, this answer seems the best (but I haven't tried it yet). Performance is not an issue since the size of the list will not be more than a few hundred, on average and this will only be called once per run.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.