Sort multiple lists based on one list C#

Object structure A class has multiple lists of data. Class List1 of double List2 of double List3 of double List4 of double

Objective: Sort multiple lists based on one list. E.g. List1 in ascending order and all other lists to follow that order to maintain individual point relativity based on index.

Initial implementations that I have tried are:

  1. Zip List2, 3 and 4 with List 1 and then sort based on List 1. Then combine sorted lists again.

e.g.

    var x1 = testData.SelectMany(d => d.xData).ToList();
    var y1 = modelData.SelectMany(d => d.yData).ToList();
    var y2 = modelData.SelectMany(d => d.y2Data).ToList();
    var sampleValues = x1.Zip(y1, (x, y) => new { X = x, Y = y }).OrderBy(v => v.X);
    var sampleValues1 = x1.Zip(y2, (x, y) => new { X = x, Y2 = y }).OrderBy(v => v.X);`

//Next select X, Y from sampleValues and select Y2 from sampleValue2
  1. Tried using SelectMany on different lists and then put that into an anonymous type. SelectMany does not work with this as it needs definite data type to return.

Anything that I am missing in these approaches or there is another approach required to get what I am trying to achieve.

Also having a class with all this data or lists as individual rows and data inside columns is not an option for me. This is because I have a list of objects having these properties. So eventually I want to merge list data across objects sampleData lists and then sort and use that data.

Feel free to let me know in case further information is required.

Answers


There's a not well-known method Array.Sort that sorts an array according to the order of a second array. I made a small extension method that utilizes this oldie:

public static class ICollectionExtensions
{
    public static IEnumerable<TSource> SortLike<TSource,TKey>(this ICollection<TSource> source, 
                                        IEnumerable<TKey> sortOrder)
    {
        var cloned = sortOrder.ToArray();
        var sourceArr = source.ToArray();
        Array.Sort(cloned, sourceArr);
        return sourceArr;
    }
}

You can use this by calling ...

var list21 = list2.SortLike(list1);

The advantage of this method is that it's extremely fast, despite the two ToArray() calls in it. ToArray() creates a shallow copy of the collection, which only takes a couple of milliseconds with a list of 10 million items. Array.Sort is fast because it selects the best sorting algorithm for the size of the array.


You could do this:

var listA = new List<double> { 1.0, 2.0, 3.0 };
var listB = new List<double> { 1.1, 2.1, 3.1 };
var listC = new List<double> { 1.2, 2.2, 3.2 };
var listD = new List<double> { 1.3, 2.3, 3.3 };

var items = new List<Tuple<double, double, double, double>>();
for (var i = 0; i < listA.Count; ++i)
    items.Add(Tuple.Create(listA[i], listB[i], listC[i], listD[i]));

var sorted = items.OrderBy(x => x.Item1);

listA = sorted.Select(x => x.Item1).ToList();
listB = sorted.Select(x => x.Item2).ToList();
listC = sorted.Select(x => x.Item3).ToList();
listD = sorted.Select(x => x.Item4).ToList();

You're probably better off doing something like:

public class MyClass
{
    public double A { get; set; }
    public double B { get; set; }
    public double C { get; set; }
    public double D { get; set; }
}

And then work on List<MyClass> instead of four different lists.


Here you go

double[] input1 = ..., input2 = ..., input3 = ..., input4 = ...;
var sortIndex = Enumerable.Range(0, input1.Count).OrderBy(i => input1[i]).ToList();
var output1 = sortIndex.Select(i => input1[i]).ToList();
var output2 = sortIndex.Select(i => input2[i]).ToList();
var output3 = sortIndex.Select(i => input3[i]).ToList();
var output4 = sortIndex.Select(i => input4[i]).ToList();

Need Your Help

IIS 7.0 configuration issue in Windows Server 2008

asp.net iis

I have configured the IIS / our web application in two Windows 2008 Server. One is working fine and the other one is facing User Rights / Security Issue.

Replacing an ImageView Image Correctly

java android

I am currently making an android application that is Hangman and i need to update my ImageView with every time the user guesses a letter that is not in the phrase but it updates oddly, it doesn't d...