2015-12-04 131 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();