在对象C#列表中搜索属性

时间:2018-08-30 00:19:44

标签: c#

有人员和搜索对象的列表。搜索对象是对主列表进行搜索。

public class Person
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public DateTime DOB { get; set; }
    public int Zip { get; set; }
    public string OtherDetails { get; set; }
}

public class SearchParam
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public DateTime? DOB { get; set; }
}

我正在使用SearchParam对象在List<Person>上进行搜索。 我的搜索功能如下:

List<Person> GetResult(SearchParam search, List<Person> persons)
{
    if (search == null && persons == null)
    {

        if (!string.IsNullOrWhiteSpace(search.FirstName)
            && string.IsNullOrWhiteSpace(search.LastName)
            && !search.DOB.HasValue
            )
        {
            return persons.Where(p => p.FirstName.ToUpper().StartsWith(search.FirstName.ToUpper())).ToList();
        }

        if (string.IsNullOrWhiteSpace(search.FirstName)
            && !string.IsNullOrWhiteSpace(search.LastName)
            && !search.DOB.HasValue
            )
        {
            return persons.Where(p => p.LastName.ToUpper().StartsWith(search.LastName.ToUpper())).ToList();
        }

        if (string.IsNullOrWhiteSpace(search.FirstName)
            && string.IsNullOrWhiteSpace(search.LastName)
            && search.DOB.HasValue
           )
        {
            return persons.Where(p => p.DOB.Equals(search.DOB)).ToList();
        }

        if (!string.IsNullOrWhiteSpace(search.FirstName)
            && !string.IsNullOrWhiteSpace(search.LastName)
            && !search.DOB.HasValue
           )
        {
            return persons.Where(p => p.FirstName.ToUpper().StartsWith(search.FirstName.ToUpper())
                    && p.LastName.ToUpper().StartsWith(search.LastName.ToUpper())).ToList();
        }

        if (!string.IsNullOrWhiteSpace(search.FirstName)
           && !string.IsNullOrWhiteSpace(search.LastName)
           && search.DOB.HasValue
           )
        {
            return persons.Where(p => p.FirstName.ToUpper().StartsWith(search.FirstName.ToUpper())
                    && p.LastName.ToUpper().StartsWith(search.LastName.ToUpper())
                    && p.DOB.Equals(search.DOB)).ToList();
        }
        return persons;
    }
    else
    {
        return persons;
    }
}

此代码“ GetResult”正在工作,但对此我不满意。 我应该如何处理列表和搜索对象中的空值,并尽量减少此方法中的代码行?

3 个答案:

答案 0 :(得分:2)

使用Linqs流水线

var workingList = persons;

if(searchParam.FirstName != null)
  workingList = workingList.Where(p=>p.FirstName.Startswith(searchParam.FirstName));

if(searchParam.LastName != null)
  workingList = workingList.Where(p=>p.LAstName.StartsWith(searchParam.LastName));

etc.

最后

return workingList.ToList();

即一次组装一个过滤器,然后最后进行枚举

答案 1 :(得分:1)

我建议使用少于return的方法。

这是我的尝试:

/// <summary>
/// Returns a filtered list of persons
/// </summary>
/// <param name="search">Filters. Only filters that are set (not null or empty) are applied</param>
/// <param name="persons">List to filter</param>
/// <returns>Filtered list or a new list of all persons if no filters provided</returns>
/// <exception cref="ArgumentNullException"> Thrown if 'search' or 'persons' is null </exception>
static List<Person> Filter(SearchParam search, IEnumerable<Person> persons)
{
    if( search == null ) throw new ArgumentNullException(nameof(search));
    if (persons == null) throw new ArgumentNullException(nameof(persons));

    IEnumerable<Person> filtered = persons;

    if( !string.IsNullOrEmpty(search.FirstName))
    {
        filtered = filtered.Where( p => string.Compare( p.FirstName, search.FirstName, StringComparison.CurrentCultureIgnoreCase ) == 0);
    }

    if (!string.IsNullOrEmpty(search.LastName))
    {
        filtered = filtered.Where(p => string.Compare(p.LastName, search.LastName, StringComparison.CurrentCultureIgnoreCase) == 0);
    }

    if (search.DOB.HasValue)
    {
        //This filter should probably allow searching only by year, etc.
        filtered = filtered.Where(p =>p.DOB == search.DOB);
    }

    return filtered.ToList();
}

和示例

List<Person> l = new List<Person>();

l.Add(new Person
{
    FirstName = "Prashant",
    DOB = new DateTime(1990, 01, 02)
});
l.Add(new Person
{
    FirstName = "TymTam",
    LastName = "No Choc",
    DOB = new DateTime(1977, 01, 02)
});
l.Add(new Person
{
    FirstName = "Melissa",
    LastName = "No Choc",
    DOB = new DateTime(1977, 01, 02)
});

var filter = new SearchParam()
{
    LastName = "No CHOC",
    DOB = new DateTime(1977, 01, 02)
};

var filtered = Filter(filter, l);
foreach( var f in filtered)
{
    Console.WriteLine($"{f.FirstName} {f.LastName} ({f.DOB})");
}

结果:

TymTam No Choc (2/01/1977 00:00:00)
Melissa No Choc (2/01/1977 00:00:00)

别忘了单元测试!

答案 2 :(得分:0)

您可以使用以下代码最小化if-else子句和嵌套块:

public static List<Person> GetResult(SearchParam search, List<Person> persons)
{
    if (search == null || persons == null)
    {
        return persons;
    }

    var ignoreCase = StringComparison.CurrentCultureIgnoreCase;
    var firstNamePrefix = string.IsNullOrWhiteSpace(search.FirstName) ? "" : search.FirstName;
    var lastNamePrefix = string.IsNullOrWhiteSpace(search.LastName) ? "" : search.LastName;

    return persons.Where(p => p.FirstName.StartsWith(firstNamePrefix, ignoreCase))
                  .Where(p => p.LastName.StartsWith(lastNamePrefix, ignoreCase))
                  .Where(p => p.DOB.Equals(search.DOB ?? p.DOB))
                  .ToList();
}

P.S。我冒昧地将您的第一个条件取反,即检查参数是否为null。