mjaniaut Ответов: 2

Вложенный список как извлечь с помощью linq


Привет,

У меня был какой-то вложенный список, и я хотел бы извлечь сложную информацию, но я не знаю, как написать выражение linq.



public class Section
{
      public List<Side> SideList {get; set; } = new List<Side>()
}

public class Side
{
      public List<PositionSide> PositionList {get; set; } = new List<PositionSide>()
}

public class PositionSide : 
{
      public int Position {get; set;}
      ....
}

Я хотел бы извлечь список сторон, где позиция выше 0 и ниже 6, но когда я делаю запрос :
List<side> listNozzleBySide = SectionList.SelectMany(x => x.SideList.Where(y => y.PositionList.Any(z => z.Position >= 1 && z.Position <=5))).ToList();


позиции 0 и 6 остальных присутствуют в списке боковых.

например у меня есть это в списке

section 1 
 Side 1
  Position 0
  Position 1
  Position 2
  Position 3
  Position 4
  Position 5
  Position 6


Я хотел бы иметь это :
Section 1
  Side 1
    Position 1
    Position 2
    Position 3
    Position 4
    Position 5


Что я уже пробовал:

List<side> listNozzleBySide = SectionList.SelectMany(x => x.SideList.Where(y => y.PositionList.Any(z => z.Position >= 1 && z.Position <=5))).ToList();

Richard MacCutchan

И что же? Какой результат дал ваш код?

F-ES Sitecore

"Any" просто возвращает true, если выполняется условие внутри. Ваш код запрашивает боковой объект, где есть какие-либо позиции >=1 1 и <=5. На самом деле он не фильтрует позиции вниз, чтобы соответствовать этим критериям, поэтому ваша сторона возвращается со всеми нетронутыми позициями.

После того как вы получите свой список побочных объектов, просто повторите их и удалите все, что не находится в нужном диапазоне.

2 Ответов

Рейтинг:
7

Maciej Los

Цитата:
Я хотел бы извлечь список сторон, где позиция выше 0 и ниже 6, но когда я делаю запрос :
List<side> listNozzleBySide = SectionList.SelectMany(x => x.SideList.Where(y => y.PositionList.Any(z => z.Position >= 1 && z.Position <=5))).ToList();

позиции 0 и 6 остальных присутствуют в списке боковых.


Что ж... я постараюсь объяснить это. Представьте себе, что у вас есть 120 учеников в 4 классах (30 учеников в классе). Вы хотите получить студентов с красными носками на ногах. Предположим, что в каждом классе есть хотя бы один ученик с красными носками, каждый класс соответствует вашим критериям. Понял?
Если нет, вы должны получить студентов вместо классов.

Что касается вашего примера, то вы должны получить позиции вместо сторон.

Взгляните на пример:
void Main()
{
	School school = new School(){Classes = new List<SchoolClass>()
		{
			new SchoolClass(){ClassID = 1, ClassName="A", Students = new List<Student>()
				{
					new Student(){StuID = 1, Name="Maciej", ColorOfSocks="yellow"},
					new Student(){StuID = 5, Name="Anna", ColorOfSocks="red"},
					new Student(){StuID = 22, Name="Robert", ColorOfSocks="green"}
				}},
			new SchoolClass(){ClassID = 2, ClassName="B", Students = new List<Student>()
				{
					new Student(){StuID = 2, Name="Fred", ColorOfSocks="black"},
					new Student(){StuID = 3, Name="Viana", ColorOfSocks="gray"},
					new Student(){StuID = 21, Name="Julia", ColorOfSocks="red"}
				}}
		}};
	
	var cla = school.Classes.Where(c=>c.Students.Any(s=>s.ColorOfSocks=="red"));
	//returns the list of all existing classes, because in each class there's at least one studnet with red socks!
	
	var stu = school.Classes.Select(c=>c.Students.Where(s=>s.ColorOfSocks=="red"));
	//returns the list of students which meets the criteria: {color of socks = red}
	
}

// Define other methods and classes here

public class School
{
	public List<SchoolClass> Classes = new List<SchoolClass>();
}

public class SchoolClass
{
    public int ClassID {get; set;}
	public string ClassName {get; set;}
	public List<Student> Students = new List<Student>();
}

public class Student
{
	public int StuID {get; set;}
	public string Name {get; set;}
	public string ColorOfSocks {get; set;}
	
}


Рейтинг:
17

OriginalGriff

Игнорируя то, что ваш пример кода не будет компилироваться - всегда проверяйте, что ваш код работает и создает проблему в упрощенном виде, или мы все тратим кучу времени, работая над плохим кодом - любая ваша проблема.
Any возвращает bool: true, если какой-либо отдельный элемент последовательности соответствует условию, false, если ни один элемент последовательности не соответствует. Таким образом, если какой-либо элемент находится в диапазоне от 1 до 5 включительно, то все элементы являются допустимыми и будут включены в выходные данные.
Наверное, то, что вы хотите, ближе к этому:

var s1 = SectionList.Select(sections => sections.SideList.Select(sides => sides.PositionList.Where(ps => ps.Position >= 1 && ps.Position <= 5))).ToList();
Но трудно сказать с тем, что Вы нам дали.