0

So I have a particular issue.

I have a standard 2D array (non-jagged) and a string array. They are linked lets just say via the 1st column of the 2D array.

So that means I would like to sort them together (its not a key based system so I can't use the columns as keys into the string array, just when ever a row in the 2D array moves so too shall the value in equivalent row of the string array move).

Not sure what is the best solution here. The dirty method that I have tried and works is standard nested loops to sort via the first column and move everything accordingly.

I just want to know if there is a better solution than this, perhaps using Linq and things like that??

7
  • 4
    Could you show an example? Also, if they are to be sorted together maybe a better structure is needed? A class containing to two? (that will contain a column and a string, and to have a list of that class) Commented Jul 26, 2018 at 15:10
  • Why is a "standard nested loop" dirty? Commented Jul 26, 2018 at 15:10
  • Would a Dictionary<string,int[,]> not work better in this case? dotnetperls.com/sort-dictionary i assumed the OP is looking for a column and row relationship between his string[] and value[,] arrays. something like string[0]="Cell1" Cells[0,0]=0 Cells[0,1]=1 etc i wanted to keep it short as i also assumed the OP didn't hear of the map/dict which if my assumption above is correct the OP would be better having a key/value relationship and using the tools provided Commented Jul 26, 2018 at 15:14
  • It would help if you could include code to illustrate your issue Commented Jul 26, 2018 at 15:15
  • Something like this or this? Commented Jul 26, 2018 at 15:20

1 Answer 1

0

TLDR:

private (int[,], string[]) SortByColumnNames(int[,] array, string[] columnNames)
{
    var columnNameToIndex = columnNames.Select((c, index) => Tuple.Create(c, index));
    var sortedColumns = columnNameToIndex.OrderBy(ci => ci.Item1, StringComparer.OrdinalIgnoreCase).ToList();
    var sortedArray = new int[2, 3];
    for (var newColumnIndex = 0; newColumnIndex < sortedColumns.Count; newColumnIndex++)
    {
        var oldColumnIndex = sortedColumns[newColumnIndex].Item2;
        for (var rowIndex = 0; rowIndex < array.GetLength(1); rowIndex++)
        {
            sortedArray[newColumnIndex, rowIndex] = array[oldColumnIndex, rowIndex];
        }
    }
    var resultColumnNames = sortedColumns.Select(ci => ci.Item1).ToArray();
    return (sortedArray, resultColumnNames);
}

Idea:

  • Create list of structures: column name + column index
  • Order this array by column name
  • New list will have ordered column names and old column indexes
  • Create new structure and fill it with the following logic: row should be the same, however column should be new.

In the other words:

  • We remember column indexes
  • Sort columns (and don't forget indexes)
  • Create map: from old index to new
  • Create new dictionary where sortedArray[newColumnIndex, rowIndex] = array[oldColumnIndex, rowIndex]
Sign up to request clarification or add additional context in comments.

1 Comment

Will give this a try as well, thank you for the solution.

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.