0

I have a tuple dataframe of multiple data types

public static void Main(string[] args) {

    int[] a = {  1,  0,  3,  4,  0};
    int[] b = {  3,  0,  9, 10,  0};
    int[] c = {  2,  3,  3,  5,  0};

    var ret = new Dictionary<string, int[]>();
    ret.Add("Jack", a);
    ret.Add("Jane", b);
    ret.Add("James", c);

    var dataframe = new Tuple<string[], Dictionary<string, int[]>, string[]>(
        new string[] { "Game 1", "Game 2", "Game 3", "Game 4", "Game 5" },
        ret,
        new string[] { "A", "B", "C", "B", "A" }
    );

The values in dataframe.item1and dataframe.item3 are different labels for the columns in dictionary in dataframe.item2. I want to sort items in the tuple including the order of arrays in the dictionary alphabetically by dataframe.item3.

So dataframe.item3 would be {"A","A","B","B","C"}

dataframe.item1 would be {"Game 1","Game 5","Game 2","Game 4","Game 3"}

dataframe.item2["Jack"] would be {1, 0, 0, 4, 3}

Here is what I tried

//Sorting the dictionary
Dictionary<string, int[]> sortedDict = new  Dictionary<string, int[]>();
for each (var item in dataframe.Item2)
{
    Array.Sort(dataframe.Item3,dataframe.Item2[item])
}


//Sorting the strings and creating a new dataframe
var sorted_dataframe = new Tuple<string[], Dictionary<string, int[]>, string[]>(
    Array.Sort(dataframe.Item3, dataframe.Item1),
    sortedDict,
    Array.Sort(dataframe.Item3)
);
Alex Netkachov
  • 13,172
  • 6
  • 53
  • 85
ccsv
  • 8,188
  • 12
  • 53
  • 97

2 Answers2

1

I think the best way to solve this is to rethink you how structure your data.

For example, if you had an array of these instead (comments show an example first element):

public class GameScores
{
    // A
    public string SortKey { get; set; }
    // Game1
    public string GameLabel { get; set; }
    // { { "Jack", 1 }, { "Jane", 3 }, ... }
    public Dictionary<string, int> { get; set; }
}

Then you can sort based on the SortKey (those A, B, and C) and keep your score data together with the column. Shuffle your data to get it into a GameScores[], and you can use Array.Sort. Or just use Linq's OrderBy on an IEnumerable<GameScores>.

31eee384
  • 2,748
  • 2
  • 18
  • 27
1

Well, I would recommend to copy the data to another structure, more suitable for sorting:

Game { Name Players Code }

and just use Linq's OrderBy(...), but it looks like you prefer this structure. If so and you can tolerate k*n*log(n) complexity, you can copy the third array to temporary buffer and then sort all the arrays by copy of this buffer:

var tmp = new string[dataframe.Item3.Length];
Array.Copy(dataframe.Item3, tmp, tmp.Length);

var t = new string[dataframe.Item3.Length];
Array.Copy(tmp, t, t.Length);
Array.Sort(t, dataframe.Item1);
foreach (var v in dataframe.Item2) {
    t = new string[dataframe.Item3.Length];
    Array.Copy(tmp, t, t.Length);
    Array.Sort(t, v.Value);
}
t = new string[dataframe.Item3.Length];
Array.Copy(tmp, t, t.Length);
Array.Sort(t, dataframe.Item3);

However, I really recommend to follow the first one - copy the data to the more appropriate structure. It will be much faster.

Alex Netkachov
  • 13,172
  • 6
  • 53
  • 85