按参数排序集合linq查询

时间:2012-10-21 10:21:05

标签: c# linq

有一个List,SomeObject有属性TargetObject。 我需要创建一个List,SomeObjects跟随TargetObject。

SO_1(TO_1)| SO_2(TO_2)| SO_3(TO_3)| SO_4(TO_1)| SO_5(TO_1)| SO_6(TO_1)| SO_7(TO_1)| SO_8(TO_2)| SO_9(TO_2)| SO_10(TO_4)

必须变成

SO_1(TO_1)| SO_2(TO_2)| SO_3(TO_3)| SO_10(TO_4)| SO_4(TO_1)| SO_8(TO_2)| SO_6(TO_1)| SO_9(TO_2)| SO_7(TO_1)| SO_5(TO_1)

最后我想运行带有MaxDegreeOfParallelism = 5的Parallel.ForEach(List),因此每个5个项目的循环将永远不会同时具有相同的TargetObject。

由于

2 个答案:

答案 0 :(得分:1)

最简单的方法(至少是我能想到的最简单的方法)是首先按TargetObject对它们进行排序,然后按TargetObject对它们进行分组,并一次使用每个组中的一个元素重建集合。

List<SomeObject> CustomSort( List<SomeObject> list)
{

  var ordered = list.OrderBy(x => x.TargetObject); // might not be necessary. Not sure if group by orders the group or not.
  var groups = ordered.GroupBy(x => x.x.TargetObject);
  List<SomeObject> res = new List<SomeObject>();

  int position = 0;
  while(res.Count < list.Count)
  {
    foreach (var grp in groups)
    {
        SomeObject current = grp.ElementAtOrDefault(position);
        if ( current != null) res.Add(current);
    }
    position ++;
  }
  return res;
}

PS:此代码未经过优化,但仅用于演示该方法。

答案 1 :(得分:0)

这是我用于不同目的的InterlaceBy扩展方法但它似乎适用于您的情况。

List<int> list = new List<int>() {1,2,3,1,1,1,1,2,2,4 }; //your TO's
var newlist = list.InterlaceBy(x => x).ToList(); //1,2,3,4,1,2,1,2,1,1

public static partial class MyExtensions
{
    public static IEnumerable<T> InterlaceBy<T, S>(this IEnumerable<T> input, Func<T, S> selector)
    {
        return input
              .GroupBy(selector)
              .SelectMany(g => g.Select((x, i) => new { key = i, value = x }))
              .OrderBy(x => x.key)
              .Select(x => x.value);
    } 
}