0

I encountered a problem in my work recently, the following is the source code,

this.NameList = new ObservableCollection<Name>();

        List<Others> others1 = new List<Others>();
        others1.Add(new Others() { Company = "Company1", School = "School1" });
        others1.Add(new Others() { Company = "Company1", School = "School1" });
        others1.Add(new Others() { Company = "Company1", School = "School1" });

        List<Others> others2 = new List<Others>();
        others2.Add(new Others() { Company = "Company2", School = "School2" });
        others2.Add(new Others() { Company = "Company2", School = "School2" });
        others2.Add(new Others() { Company = "Company2", School = "School2" });

        List<Others> others3 = new List<Others>();
        others3.Add(new Others() { Company = "Company3", School = "School3" });
        others3.Add(new Others() { Company = "Company3", School = "School3" });
        others3.Add(new Others() { Company = "Company3", School = "School3" });

        this.NameList.Add(new Name() { FirstName = "Jacob", LastName = "Deng", Others = others1 });
        this.NameList.Add(new Name() { FirstName = "David", LastName = "Xu", Others = others2 });
        this.NameList.Add(new Name() { FirstName = "Helen", LastName = "Liu", Others = others3 });

please click here to see the output of above code

And then please read the following code,

  List<Others> others1 = new List<Others>();
        others1.Add(new Others() { Company = "Company1", School = "School1" });
        others1.Add(new Others() { Company = "Company1", School = "School1" });
        others1.Add(new Others() { Company = "Company1", School = "School1" });

        List<Others> others2 = new List<Others>(); 
        List<Others> others3 = new List<Others>();

        this.NameList.Add(new Name() { FirstName = "Jacob", LastName = "Deng", Others = others1 });
        this.NameList.Add(new Name() { FirstName = "David", LastName = "Xu", Others = others2 });
        this.NameList.Add(new Name() { FirstName = "Helen", LastName = "Liu", Others = others3 });

Please click here for the output of the second snippet code

From above two snippets, you might notice that the second snippet doesn't contain any items in other2 and other3, you can easily understand from the preview output.

Now the question comes, how do we use LINQ to IEnumerable to handle such case, how to use LINQ to remove those items from Others entity? but we need to keep other2 and other3 not to be null (keep it count is 0). Besides LINQ, are there any other solutions?

I tried to use the following, but failed,

var others = ((MyVM)DataContext).NameList.Select(n => n.Others.Where(o => o.School == "School1")).ToList();

I just did some test, if we don't use LINQ, then we can use the following snippet code to fix my it.

ObservableCollection<Name> nameList = ((MyVM)DataContext).NameList;
        foreach(Name n in nameList)
        {
            List<Others> removeList = new List<Others>();
            for(int i=0;i<n.Others.Count;i++)
            {
                if(n.Others[i].School!="School1")
                {
                    removeList.Add(n.Others[i]);
                }
            }
            foreach(Others other in removeList)
            {
                n.Others.Remove(other);
            }
        }

But it looks very redundant, and we know that LINQ is very useful and i believed that it can be fixed with LINQ. Hope someone could help me to fix it with LINQ,thanks.

Appreciate if someone could help me. Thanks a lot.

Jacob
  • 91
  • 2
  • 10
  • Try this : var others = ((MyVM)DataContext).NameList.Select(n => n.Others.Select(o => (o.School == "School1") ? o : "Add code here to do something else")).ToList(); – jdweng May 07 '16 at 10:03
  • Thanks Jdweng, i just want to remove those items that School is not equals to 'School1' with LINQ, and the output is the same as the second snippet code as mentioned above. Could you help me? – Jacob May 07 '16 at 10:13
  • It means when o.School !='School1', then remove the item from Others entity – Jacob May 07 '16 at 10:14

2 Answers2

2

It's better to use List<T>.RemoveAll in your case. See Using LINQ to remove elements from a List<T> for more details.

ObservableCollection<Name> nameList = ((MyVM)DataContext).NameList;
foreach(Name n in nameList)
{
    n.Others.RemoveAll(s => s.School != "School1");
}

Linq is good at read-only iterating instead of updating/deleting. If you insist using Linq, you have to re-construct each item.

var newList =   from nl in this.namelist
                // this list can be empty but never null
                let notSchool1 = (from s in nl.Others
                                  where s.School != "School1"
                                  select s).ToList()
                select new Name 
                { 
                    FirstName = nl.FirstName,
                    LastName = nl.LastName,
                    Others = noSchool1
                };
this.NameList = new ObservableCollection<Name>(newList);

Above code may break other functionalities in your application, because these items are observed.

Community
  • 1
  • 1
qxg
  • 6,955
  • 1
  • 28
  • 36
0

As I understand your question, You want to remove others whose school value is not 'School1'. There are different way available for that but I recommend to filter the data from NameList which you want.

You can try below code to get others list with 'School1'

var result = NameList.Select(name => new Name()
            {
                FirstName = name.FirstName,
                LastName = name.LastName,
                Others = name.Others.Where(obj => obj.School == "School1").ToList()
            }
            ).ToList();
Jignesh Thakker
  • 3,638
  • 2
  • 28
  • 35