选择离某个数字最近的年龄中最高的一个

4

我觉得我一直在看我的代码。

但我的问题是,我有一个无序列表,我需要选择与输入最接近或等于一个数字的对象。

我创建了这个小样例来说明我要做什么。

public class Person
{
    public string Name { get; set; }
    public int Age { get; set; }
}

var persons = new List<Person>
{
    new Person {Age = 10, Name = "Aaron"},
    new Person {Age = 15, Name = "Alice"},
    new Person {Age = 20, Name = "John"},
    new Person {Age = 22, Name = "Bob"},
    new Person {Age = 24, Name = "Malcom"}
};

int i = 17; //should return 'Alice 15'    
int y = 22; //should return 'Bob 22

2
21会返回John还是Bob?13会返回Aaron还是Alice? - Kendall Frey
5个回答

9
var person = persons.Where(p => p.Age <= input).OrderByDecending(p => p.Age).First();

首先,排除大于input(即您的iy)的数字。然后开始排序,并仅取第一个结果。


1
你可以用更简单、更能表达意图的 Max(p => p.Age) 替换掉 OrderByDescending(p => p.Age).First() - Steven
@abatishchev - 这取决于意图。 - Daniel A. White
1
@Steven - 不,那只会返回最大年龄,而不是Person - Daniel A. White
@DanielA.White:你说得对。他想要的是人,而不是年龄。 - Steven

3
比起对整个集合进行排序(这可能会在大型输入集合上变得昂贵),使用MoreLinq项目的MaxBy更加高效:
var person = persons.Where(p => p.Age <= input)
                    .MaxBy(p => p.Age);

MaxBy() 是 Jon Skeet 的 morelinq 库 的一个成员。 - Dan Busha

1
var nearest = persons.OrderBy(p => Math.Abs(p.Age - i)).First();

使用 Math.Abs 获取绝对差异,返回年龄最接近输入值的人。


1
@AdrianIftode:那么OP已经更改了需求,因为我这里仍然有他的样本数据副本,并附有以下注释:“int i = 14; //应返回'Alice 15'”。 - Tim Schmelter
然后需要做的就是剪辑掉所有年龄大于该数字的人。这是一个简单的修复。 - Andrew T Finnell
@AndrewFinnell:我不确定我是否理解了。是的,我可以很容易地修复它,但我假设其他人已经发布了正确的解决方案。不过我还是保留它,也许OP会再次改变他的意见 ;) - Tim Schmelter

0

这是一个我准备的例子,希望能对你有所帮助

     List<int> list = new List<int> { 10, 15, 20, 22, 24 };
        int number = 17;
        int closest = list.Aggregate((x, y) => Math.Abs(x - number) < Math.Abs(y - number) ? x : y);
        Label2.Text = closest.ToString();

0
你遍历列表并存储你的整数减去年龄的绝对值。将Person存储在一个变量中,直到出现差异更小的人。如果相同,则存储年龄较高的那个。完成。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接