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??

Fuzzybear
  • 1,388
  • 2
  • 25
  • 42
Vengeful
  • 9
  • 3
  • 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) – Gilad Green Jul 26 '18 at 15:10
  • Why is a "standard nested loop" dirty? – Kenneth K. Jul 26 '18 at 15:10
  • It would help if you could include code to illustrate your issue – madd0 Jul 26 '18 at 15:15
  • Something like [this](https://stackoverflow.com/questions/3355928/c-sharp-sort-list-based-on-another-list) or [this](https://stackoverflow.com/questions/3470098/list-sort-based-on-another-list)? – Magnetron Jul 26 '18 at 15:20
  • This begs for an [MCVE](https://stackoverflow.com/help/mcve). – Gert Arnold Jul 26 '18 at 17:47
  • Would a `Dictionary` not work better in this case? https://www.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 – Courtney The coder Jul 26 '18 at 15:14
  • Amazing replies here, thank you for pointing me in a better direction. I'm pretty sure all suggestions will work. Will implement them based on the feedback given. If I have any issues, will revert back, but I doubt it. Thanks. – Vengeful Jul 30 '18 at 06:25

1 Answers1

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]
Manushin Igor
  • 3,398
  • 1
  • 26
  • 40