基于一个列表C#对多个列表进行排序
对象结构类具有多个数据列表。 Class List1 of double List2 of double List3 of double List4 of double
目标:根据一个列表对多个列表进行排序。 例如List1
按升序排列,所有其他列表遵循该顺序以维持基于索引的单个点相关性。
我尝试过的初始实现是:
- Zip
List2
和4 with List 1然后基于List 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 => vX); var sampleValues1 = x1.Zip(y2, (x, y) => new { X = x, Y2 = y }).OrderBy(v => vX);` //Next select X, Y from sampleValues and select Y2 from sampleValue2
- 尝试在不同的列表上使用
SelectMany
,然后将其放入匿名类型。SelectMany
不能使用它,因为它需要返回确定的数据类型。
我在这些方法中缺少的任何东西,或者需要另一种方法来获得我想要实现的目标。
还有一个包含所有这些数据或列表的类作为列中的单个行和数据,对我来说不是一个选项。 这是因为我有一个具有这些属性的对象列表。 所以最终我想要跨对象sampleData列表合并列表数据,然后对这些数据进行排序和使用。
如果需要进一步的信息,请随时告诉我。
有一个不太知名的方法Array.Sort
,它根据第二个数组的顺序对数组进行排序。 我做了一个小扩展方法,利用这个老人:
public static class ICollectionExtensions { public static IEnumerable SortLike(this ICollection source, IEnumerable 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
很快,因为它为数组的大小选择了最佳的排序算法。
你可以这样做:
var listA = new List { 1.0, 2.0, 3.0 }; var listB = new List { 1.1, 2.1, 3.1 }; var listC = new List { 1.2, 2.2, 3.2 }; var listD = new List { 1.3, 2.3, 3.3 }; var items = new List>(); 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
而不是四个不同的列表。
干得好
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();