根据LINQ字段获取列表中的下一个项目

时间:2013-12-01 22:15:55

标签: c# linq list

我有一份员工名单,我想根据他们的状态选择列表中的下一个人。我手边没有源代码,但基本上我的列表是这样形成的。

public class Employee
{
    public string Name { get; set; }
    public string Status{ get; set; }

        public Employee( string name, string status )
        {
            this.Status = status;
            this.Name = name;
        }
}

我添加了这样的项目。

        List<Employee> r = new List<Employee>();
        r.Add( new Employee( string Name, string status );

我需要的是一种以起始名称搜索列表的方式,比如说“Bob Smith”,并让列表中的下一个人具有状态为“是”。然而,如果它在列表的末尾,我会在开始时回头直到我再次访问“Bob Smith”。

我尝试了一堆for循环,但它很麻烦且很笨拙,最糟糕的是,它没有用。

这将全部在一个返回字典列表的函数中,所以我可以将它与另一个函数一起使用。在psuedo-code中,我希望它有点像这样工作,所以我可以在for循环中遍历名称字典,使用int从中获取项目。

    public Dictionary<int,string> listToMail( int employeeNeeded )
    {
        Dictionary<int, string> tmpList = new Dictionary<int, string>();

        string lastEmployee = getLastEmployee();

        for( int x = 0; x < employeeNeeded; x++ )
        {
            /* find the next in the list that has a "yes" status. 
               If at the end of the list, start back at the beginning until we 
               reach the start by. If nothing found, exit out.*/

            tmpList.Add( x, EmployeeName );
        }

        if ( tmpList.Count > 0 )
        {
            return tmpList;

        } else {

            return null;
        }

    }

3 个答案:

答案 0 :(得分:2)

var person = 
   r.SkipWhile(e => e.Name != "Bob Smith") // skip people until Bob Smith
    .Skip(1) // go to next person
    .SkipWhile(e => e.Status != "yes") // skip until status equal 'yes'
    .FirstOrDefault(); // get first person, if any

if (person == null)
    person = r.TakeWhile(e => e.Name != "Bob Smith")
              .FirstOrDefault(e => e.Status != "yes");

答案 1 :(得分:0)

我使用lazyberezosky方法,但包括所有情况,它不是很优雅,但它有效;):

        List<Employee> list = new List<Employee>();
        list.Add(new Employee("Walter White", "yes"));
        list.Add(new Employee("Bob Smith", "no"));
        list.Add(new Employee("Walter Junior", "no"));

        //get first employee after Bob with status "yes"
        Employee result = list.SkipWhile(e => e.Name != "Bob Smith") // skip people until Bob Smith
                         .Skip(1) // go to next person
                         .SkipWhile(e => e.Status != "yes") // skip until status equal 'yes'
                         .FirstOrDefault(); // get first person, if any

        if (result == null)
        {
            //get the first employee in list with status "yes"
            result = list.SkipWhile(e => e.Status != "yes") // skip until status equal 'yes'
                         .FirstOrDefault(); // get first person, if any

            if (result == null)
            {
                //get Bob Smith if no employee has status "yes"
                result = list.SkipWhile(e => e.Name != "Bob Smith")
                        .FirstOrDefault();                               
            }
        }

更简单的方法是:

        Employee res = list.SkipWhile(e => e.Name != "Bob Smith") // skip people until Bob Smith
                         .Skip(1) // go to next person
                         .SkipWhile(e => e.Status != "yes")
                         .Union(list.SkipWhile(e => e.Status != "yes"))
                         .FirstOrDefault();

如果没有员工的状态为“是”,则res为空!所以注意不要访问res的值而不检查它是否为null ...

再次感谢lazyberezosky的起点;)

答案 2 :(得分:0)

认为这应该有效

public static Dictionary<int,string> listToMail(string startAtName, int needed)
    {
        var firstPart = r.SkipWhile(e => e.Name != startAtName);
        var secondPart = r.TakeWhile(e => e.Name != startAtName);

        var results = firstPart.Union(secondPart)
            .Where(e => e.Status == "yes")
            .Take(needed)
            .Select((e, i) => new { Key = i, Name = e.Name })
            .ToDictionary(kv => kv.Key, kv => kv.Name);
        if (results.Any())
            return results;
        else
            return null;
    }