2015-12-04 224 views
2

對象結構 一個類具有多個數據列表。 Class List1 of double List2 of double List3 of double List4 of double基於一個列表對多個列表排序C#

目標:根據一個列表對多個列表進行排序。例如。 List1按升序排列,其他所有列表都遵循該順序,以便根據索引維護個體點相對性。

,我已經試過初步實現是:

  1. 郵編List2,3和4表1,然後排序依據列表1.話又說回來結合的有序列表。

例如,

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 
  • 上不同列表使用SelectMany並然後將其寫入一個匿名類型試過。 SelectMany不適用於此,因爲它需要返回確定的數據類型。
  • 任何我在這些方法中失蹤或有另一種方法需要得到我想要實現的。

    此外,將所有這些數據或列表作爲單獨的行和列中的數據的類也不適合我。 這是因爲我有一個具有這些屬性的對象列表。所以最終我想跨對象sampleData列表合併列表數據,然後對這些數據進行排序和使用。

    隨時讓我知道,以防萬一需要進一步的信息。

    +4

    這裏有什麼地方存在特定問題嗎?或者你只是想讓我們爲你做你的功課? –

    +1

    任何你沒有將四個值包裝在類,結構或元組中的原因? – Kvam

    +0

    @ roryap我已經嘗試了方法和解決方法我正在努力將這個類從不同的列表轉換爲表結構,我可以使用它來對一列進行排序。 它只是我很好奇,如果有必要有效基於一個名單上排序多個列表,並保留在這些列表中的折射率匹配的方式? 讓我知道,這聽起來像一個問題,我會很樂意更新主要問題? – Versatile

    回答

    0

    還有,根據第二陣列的順序排序的數組一個並不知名的方法Array.Sort。我做了一個小擴展方法,利用這個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; 
        } 
    } 
    

    您可以通過調用...

    var list21 = list2.SortLike(list1); 
    

    這種方法的優點是,它的速度極快,儘管這兩個ToArray()電話。 ToArray()創建集合的淺表副本,只需要幾毫秒的時間和1000萬個項目的列表。 Array.Sort速度很快,因爲它爲數組大小選擇了最佳排序算法。

    +0

    太棒了。感謝您的簡潔解決方案。這是一個很好的學習! – Versatile

    0

    您可以使用下面的代碼來實現此目的,但請考慮上述關於將數據重新分解爲結構或類的註釋。該代碼將四個數組拉到一起,然後在第一個字段上排序。

    float[] one = {4, 3, 2, 1}; 
    float[] two = {5,6,7,8}; 
    float[] three = {9,10,11,12}; 
    float[] four = { 13, 14, 15, 16 }; 
    
    var combined = one.Zip(two, (a, b) => new {a, b}). 
            Zip(three, (c, d) => new {c.a, c.b, c = d}). 
            Zip(four, (e, f) => new {e.a, e.b, e.c, d = f}). 
            OrderBy(x => x.a); 
    

    你可以得到這樣的有序陣列的背:

    var oneSorted = combined.Select(x => x.a); 
    var twoSorted = combined.Select(x => x.b); 
    var threeSorted = combined.Select(x => x.c); 
    var fourSorted = combined.Select(x => x.d); 
    
    1

    可以做到這一點:

    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(); 
    

    你可能會更好過做這樣的事情:

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

    然後在List<MyClass>上工作,而不是四個不同的列表。

    1

    在這裏你去

    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();