OrderBy由嵌套列表列出

时间:2014-08-12 08:06:22

标签: c# linq

我有一个objectA列表,每个列表都包含另一个对象列表。 我正在尝试使用(int)Id:

对每个对象列表进行排序
var sorted = objectA.OrderBy(a => a.ObjectB.OrderBy(b => b.Id)).ToList();

当然,这不起作用。有人有建议吗?

2 个答案:

答案 0 :(得分:2)

如果要对每个ObjectB列表进行排序(即修改它),则只需使用List<T>.Sort方法。您需要指定自定义Comparison<T>委托:

foreach (var a in objectA)
{
   a.ObjectB.Sort((x, y) => x.Id - y.Id)
}

如果objectAList<ObjectA>,那么您可以使用ForEach方法并传递委托:

objectA.ForEach(a => a.ObjectB.Sort((x, y) => x.Id - y.Id));

如果您不想修改原始ObjectA实例,则必须将每个ObjectA实例投影到新实例中(通过克隆它),然后分配已排序的ObjectB }列表。它看起来像(假设所有属性都有公共设置者):

var newList = objectA
    .Select(x => new ObjectA()
    {
        Id = x.Id,
        SomethingElse = x.SomethingElse,
        ObjectB = x.ObjectB.OrderBy(b => b.Id).ToList()
    })
    .ToList();

答案 1 :(得分:0)

您可以准备扩展方法并以通用方式使用它。首先,Expression的帮助者:

public static void SetProperty<T, B>(
                        this Expression<Func<T, B>> propertySelector, 
                        T target, 
                        B value)
{
  SetObjectProperty(target, propertySelector, value);
}

public static void SetObjectProperty<T, B>(
                             T target, 
                             Expression<Func<T, B>> propertySelector, 
                             object value)
{
  if (target == null)
  {
    throw new ArgumentNullException("target");
  }

  if (propertySelector == null)
  {
    throw new ArgumentNullException("propertySelector");
  }

  var memberExpression = propertySelector.Body as MemberExpression;
  if (memberExpression == null)
  {
    throw new NotSupportedException("Cannot recognize property.");
  }

  var propertyInfo = memberExpression.Member as PropertyInfo;
  if (propertyInfo == null)
  {
    throw new NotSupportedException(
                       "You can select property only."
                       + " Currently, selected member is: " 
                       + memberExpression.Member);
  }

  propertyInfo.SetValue(target, value);
}

然后写下这个扩展名:

public static IEnumerable<TSource> OrderInnerCollection<TSource, TInner, TKey>(
    this IEnumerable<TSource> source,
    Expression<Func<TSource, IEnumerable<TInner>>> innerSelector,
    Func<TInner, TKey> keySelector)
{
    var innerSelectorDelegate = innerSelector.Compile();
    foreach (var item in source)
    {
        var collection = innerSelectorDelegate(item);
        collection = collection.OrderBy(keySelector);
        innerSelector.SetProperty(item, collection);

        yield return item;
    }
}

用法:

var result = objectA.OrderInnerCollection(
                           aObj => aObj.ObjectB, 
                           objB => objB.Id).ToList();
相关问题