繁体   English   中英

C#linq有两个列表

[英]C# linq with two Lists

我陷入以下问题:我想加载一个列表,但是我可以传递多个参数,这可能是找到我想要的列表的标准。 现在,我具有以下结构:

House{
  Name;
  ID;
  Alias;
}

我也有:

Person{
  Name;
  Alias;
}

这意味着,一栋房屋可以容纳多人,而同名的多个人可以位于多栋房屋中。 所以现在我想将我的函数eG称为“ GetHouses(字符串条件)”,因为条件可能是:

  1. 房屋名称
  2. 房屋ID
  3. 房子名称的一部分
  4. 房子里一个人的名字

现在,我只读取每所房子及其数据,然后根据条件选择。

重要说明:在此之前,我无法更改逻辑!

因此,现在当我尝试查找匹配标准时,我很快就使用了LINQ。 只要我不与“人物”进行比较,它就会起作用:

result = (from x in result
where (
  (string.Equals(x.Name, criteria))
  || (string.Equals(x.ID, criteria))
  || (x.Name.Contains(criteria))
  select x).ToList();

现在,我想将每个人加载到我找到的房屋中,并检查房屋中的人名是否符合条件。 有没有办法在我已经使用的LINQ中做到这一点? 还是我必须通过以下结果查看结果:

result.ForEach(x => ...)

如果可以与LINQ一起使用,那就太好了。 我做了类似的逻辑

result.FindAll(new Predicate<House>((x) => { ... LoadPersons(criteria) {... } }));

但这花了很长时间。

亲切的问候,Asat0r

假设您的House类中有一个PersonList ,则可以使用Enumerable.Any

var matchingHouses = from house in allHouses
    where string.Equals(house.Name, criteria) 
       || string.Equals(house.ID, criteria) 
       || house.Name.Contains(criteria)
       || house.PersonList.Any(resident => string.Equals(resident.Name, criteria))
    select house;

如果您有返回“居民”的方法,则可以使用此方法。 如果以后要访问这些人,则可以创建一个匿名类型来存储他们:

var housesAndResidents = from house in allHouses
    let matchingResidentList = LoadPersons(house.ID)
       .Where(resident => string.Equals(resident.Name, criteria))
       .ToList()
    where string.Equals(house.Name, criteria) 
       || string.Equals(house.ID, criteria) 
       || house.Name.Contains(criteria)
       || matchingResidentList.Any()
    select new { house, matchingResidentList };

您可以通过以下方式访问这些属性:

var matchingHouseList = housesAndResidents.ToList(); 
// you don't need the list, you can use foreach directly,
// but whenever you access housesAndResidents you will execute that query
// ToList materializes this query into a collection, so you can enumerate it or use the Count property
foreach(var x in matchingHouseList )
{
    Console.WriteLine("House:{0} Matching-Resident(s):{1}"
        , x.house.Name
        , String.Join(", ", x.matchingResidentList.Select(r => r.Name)));
}

这是使用三个类的简单解决方案: ProgramHousePerson

House类“ houses”(双关语意味)是Person类的列表(以及您自己的值:名称,ID和别名)。 这样,居民就成为房屋的一部分,而不是存放在其他地方。 将居民存放在House类之外与将午餐盒中的物品放在背包中的框外相同。

Person存储有关房屋居民的基本信息。 在“ House类别中拥有居民列表,可以更轻松地将搜索条件与人们进行比较。

Program类中,您将找到MainFindHouses类。 这些有点解释自己

class Person
{
    public string name;
    public string alias;

    public Person(string _name, string _alias = "")
    {
        name = _name;
        alias = _alias;
    }
}

class House
{
    public string name;
    public string id;
    public string alias;
    public List<Person> people = new List<Person>();

    public House(string _name, string _id, string _alias = "")
    {
        name = _name;
        id = _id;
        alias = _alias;
    }
}

class Program
{
    static List<House> houses = new List<House>();

    static void Main(string[] args)
    {
        // Add houses here

        foreach (House house in FindHouses("criteria"))
        {
            // Do stuff
        }
    }

    // Find all the houses in which the criteria exists
    static List<House> FindHouses(string criteria)
    {
        // Return the list of all houses in which the criteria exists
        return houses.Where(h =>
            h.name.Contains(criteria) ||
            h.id == criteria ||
            h.alias.Contains(criteria) ||

            h.people.Any(p => 
            p.name.Contains(criteria) ||
            p.alias.Contains(criteria))).ToList();
    }
}

我不知道这对您的代码的更改是否太大,但是无论如何,我希望这会有所帮助。

我知道您提到过您不想将这些人放到房屋中,但这使基于“所有价值”的房屋搜索变得更加容易

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM