Reputation: 41
I would like to sort a list of objects. The structure is a Dictionary<object, double[]>
and looks like this:
Dictionary<int, double[]> dict = new Dictionary<int, double[]>{
{object1, new double[]{0.02, 0.10, 0.30, 0.5}},
{object4, new double[]{0.02, 0.10, 0.30, 0.2}},
{object3, new double[]{0.02, 0.10, 0.30, 0.3}},
{object2, new double[]{0.02, 0.10, 0.50, 0.4}}
};
The arrays should be ordered in different orders based on the index. i.e ascending for the 1st, 2nd and 4th index and descending for the 3rd index. So eventually, I should get:
object2, 0.02, 0.1, 0.5, 0.4
object4, 0.02, 0.1, 0.3, 0.2
object3, 0.02, 0.1, 0.3, 0.3
object1, 0.02, 0.1, 0.3, 0.5
I 'm using the code posted here as a starting point. What kind of adjustments should I make? Of course I understand that the method will not be generic (array length unrelated) anymore. I was considering creating a bool[]
which has the same size as the double[]
, where True
stands for ascending sorting and False
for descending, but Compare method strictly gets 2 arguments. Any help would be much appreciated. Thanks!
Upvotes: 0
Views: 112
Reputation: 1317
If I got you correctly, just try to use this comparer:
public class SequenceComparer : IComparer<IList<double>>
{
public SequenceComparer(bool[] markers)
{
Markers = markers;
}
public bool[] Markers { get; }
public int Compare(IList<double> x, IList<double> y)
{
//check for null
if (x == null || y == null || Markers == null)
{
throw new Exception("Null arrays are not valid");
}
//check identical count
if (x.Count != y.Count || x.Count != Markers.Length)
{
throw new Exception("Invalid count");
}
for (var i = 0; i < x.Count; i++)
{
if (x[i].Equals(y[i]))
{
continue;
}
var comparisonResult = x[i] > y[i] ? 1 : -1;
//if marker is false, invert comparisonResult
return Markers[i] ? comparisonResult : comparisonResult * -1;
}
//Your arrays are identical, just skip
return 1;
}
}
You can use any length arrays and regulate ordering direction with bool[]
flags
Example of using:
var query = dict.OrderBy(pair => pair.Value, new SequenceComparer(new []{true, true, false, true}));
Upvotes: 1
Reputation: 11342
You can use the Linq library. Call OrderBy
on the dictionary.
var x = dict.OrderBy(o => o.Value[0]).ThenBy(o => o.Value[1]).ThenBy(o => -o.Value[2]).ThenBy(o => o.Value[3]);
Full Code:
using System.Linq;
...........
public static void Main()
{
var object1 = 1;
var object2 = 2;
var object3 = 3;
var object4 = 4;
Dictionary<int, double[]> dict = new Dictionary<int, double[]>{
{object1, new double[]{0.02, 0.10, 0.30, 0.5}},
{object4, new double[]{0.02, 0.10, 0.30, 0.2}},
{object3, new double[]{0.02, 0.10, 0.30, 0.3}},
{object2, new double[]{0.02, 0.10, 0.50, 0.4}}
};
var x = dict.OrderBy(o => o.Value[0]).ThenBy(o => o.Value[1]).ThenBy(o => -o.Value[2]).ThenBy(o => o.Value[3]);
// write ordered values
foreach (var d in x)
{
Console.Write(d.Key + ", [");
foreach (var v in d.Value)
Console.Write(v + ", ");
Console.WriteLine("]");
}
}
Output
2, [0.02, 0.1, 0.5, 0.4, ]
4, [0.02, 0.1, 0.3, 0.2, ]
3, [0.02, 0.1, 0.3, 0.3, ]
1, [0.02, 0.1, 0.3, 0.5, ]
Upvotes: 2