C# 如何使用C Linq在ObsevableCollection中返回所有项目(如果未选择任何项目)或仅返回选定项目(如果至少选择了一个项目)?

C# 如何使用C Linq在ObsevableCollection中返回所有项目(如果未选择任何项目)或仅返回选定项目(如果至少选择了一个项目)?,c#,linq,lambda,items,C#,Linq,Lambda,Items,在以下情况下,我尝试使用Linq和Lambda在ObservableCollection中获取C中的项: 如果未选择任何项目,则返回所有项目 或 如果至少选择了一个项目,则仅返回所选项目。 MyClassSelective有一个名为Selected的bool类型属性 是否可以只在一个Linq查询行中执行此操作 谢谢。您可以先按所选属性分组。如果有已选择和未选择的项目,则这将为您提供2个组;如果所有项目均已选择或未选择,则将为您提供1个组。然后,按所选特性对组进行排序。如果有两个组,这将把包含选定

在以下情况下,我尝试使用Linq和Lambda在ObservableCollection中获取C中的项:

如果未选择任何项目,则返回所有项目 或

如果至少选择了一个项目,则仅返回所选项目。 MyClassSelective有一个名为Selected的bool类型属性

是否可以只在一个Linq查询行中执行此操作


谢谢。

您可以先按所选属性分组。如果有已选择和未选择的项目,则这将为您提供2个组;如果所有项目均已选择或未选择,则将为您提供1个组。然后,按所选特性对组进行排序。如果有两个组,这将把包含选定项目的组放在第一位。然后,返回第一组

ObservableCollection<MyClassSelectable> myClassesSelectable;

List<MyClassSelectable> result = myClassesSelectable
    // group by the Selected property
    .GroupBy(mcs => mcs.Selected)
    // order (=> true first, false second)
    .OrderByDescending(g => g.Key)
    // return the first
    .FirstOrDefault()
    ?.ToList();

为了回答@Pavel Anikhouski并更新@GregaMohorko答案,下面的代码正确地完成了这项工作

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;

namespace Test
{
    public class MyClassSelectable
    {
        public bool Selected { get; set; }
        public string Name { get; set; } = "";
    }

    public class Class1
    {

        public ObservableCollection<MyClassSelectable> myClassesSelectable = new ObservableCollection<MyClassSelectable>();

        public Class1()
        {
            myClassesSelectable.Add(new MyClassSelectable { Selected = true, Name = "Item 1" });
            myClassesSelectable.Add(new MyClassSelectable { Selected = true, Name = "Item 2" });
            myClassesSelectable.Add(new MyClassSelectable { Selected = false, Name = "Item 3" });
            myClassesSelectable.Add(new MyClassSelectable { Selected = false, Name = "Item 4" });

            IEnumerable<MyClassSelectable> myCollection = myClassesSelectable
                            // group by the Selected property
                            .GroupBy(mcs => mcs.Selected)
                            // order (=> true first, false second)
                            .OrderByDescending(g => g.Key)
                            // return the first OR an empty collection if there are no items
                            .FirstOrDefault()
                            ?.ToList();
        }

    }
}
如果选择了两个项目,它将返回两个项目的列表。 如果未选择任何项目,则返回所有4个项目。
非常感谢您的工作@GregaMohorko。

您也可以在不使用GroupBy的情况下实现相同的行为

class MainClass {
  public static void Main (string[] args) {
    var myCollection = new ObservableCollection<MyClassSelectable>();

    // Add some items of tyoe MyClassSelectable to myCollection here
    myCollection.Add(new MyClassSelectable() { Selected = true });
    myCollection.Add(new MyClassSelectable() { Selected = false });
    myCollection.Add(new MyClassSelectable() { Selected = true });
    myCollection.Add(new MyClassSelectable() { Selected = true });


    // Now get selected or all items
    var selected = GetSelectedItems(myCollection);

    Console.WriteLine($"Items selected: {selected.Count()}");
  }

  private static IEnumerable<MyClassSelectable> GetSelectedItems(ObservableCollection<MyClassSelectable> coll) {
    var selected = coll.Where(c => c.Selected);
    if (selected.Count() > 0) {
      return selected;
    }
    else {
      return coll;
    }
  }
}

为什么它需要是单个Linq查询?您可以共享整个代码示例吗?Linq方法返回一个IEnumerable在大多数情况下,你不能返回一个ObservableCollections。唯一需要的是有一个更紧凑的代码,并便于维护,而不需要几行执行相同的函数查询。我也测试了这个解决方案。它返回与此答案相同的结果。我认为这不算作一个查询。这只是利用内联if语句将所有内容堆叠到一行中。您是对的,但问题的目的还没有达到。它填充了几行代码。您是对的,但我建议使用此解决方案的原因是,您只迭代集合一次,而不是迭代列表中的项目,然后对真键和假键进行排序,最后再次将整个选定集合转换为列表。消除几行代码的开销这么大?有时候最短的解决方案不是最好的,我同意你的看法。但在我的具体案例中,CPU和内存开销不如代码清晰重要。您可能应该在最后的ToList之前添加一个问号,因为如果没有项,FirstOrDefault可以返回null,并且它将抛出NullReferenceException。请看我的最新答案。嗨@GregaMohorko,你说得对。我做了更新。顺致敬意,
return new ObservableCollection<MyClassSelectable>(myCol.Any(x => x.Selected)?myCol
.Where(x => x.Selected):myCol)