如何在lambda表达式中使用局部变量

7

我有两个某个类别的列表对象,

 class person
    {
        public string id { get; set; }
        public string name { get; set; }
    }

List<person> pr = new List<person>();
pr.Add(new person { id = "2", name = "rezoan" });
pr.Add(new person { id = "5", name = "marman" });
pr.Add(new person { id = "3", name = "prithibi" });

List<person> tem = new List<person>();
tem.Add(new person { id = "1", name = "rezoan" });
tem.Add(new person { id = "2", name = "marman" });
tem.Add(new person { id = "1", name = "reja" });
tem.Add(new person { id = "3", name = "prithibi" });
tem.Add(new person { id = "3", name = "prithibi" });

现在我需要使用lambda从“pr”ListObject中获取所有ID,该ID在“tem”ListObejct中具有无条目或奇数个条目。

为了实现这一点,我已经使用了以下方法:

HashSet<string> inconsistantIDs = new HashSet<string>(pr.Select(p => p.id).Where(p => tem.FindAll(t => t.id == p).Count == 0 || tem.FindAll(t => t.id == p).Count % 2 != 0));

它能够正常工作。

但是你可以从代码中看到,我使用了tem.FindAll(t => t.id == p).Count两次来与==0%2!=0进行比较。

有没有办法将tem.FindAll(t => t.id == p).Count保存到一个临时变量中,然后将此变量与==0%2!=0进行比较。

简单地说,我只想在这里使用一次,用于两个条件。


请不要使用“在xxx中遇到问题”的主题,那将是谷歌链接。 - Tim Schmelter
5个回答

16

是的,这可以工作。但是 "count .Count % 2 != 0" 应该改为 "count% 2 != 0"。请你纠正一下。@Ahmed KRAIEM - Rezoan
3
我会尽力进行翻译,以下是您需要翻译的内容:与其使用“FindAll”,我会使用“Count()”。前者需要为每个人创建一个新集合。 - Tim Schmelter
@Rezoan 已更正。 @Tim 是的,没错。 var count = tem.Count(t => t.id == p); - Ahmed KRAIEM

4
也许只需简单地:
var query = pr.Where(p => { int c = tem.Count(p2 => p.id == p2.id); return c == 0 || c % 2 != 0; });

返回两个人:

2   "rezoan"
5   "marman"

4

除了语句 lambda,你还可以使用 let 子句

HashSet<string> inconsistantIDs = new HashSet<string>(
    from p in pr
    let count = tem.FindAll(t => t.id == p).Count
    where count == 0 || count % 2 != 0
    select p.id
);

2
HashSet<string> inconsistantIDs = new HashSet<string>(
    pr.Select(p => new { Id = p.id, Cnt = tem.FindAll(t => t.id == p.id).Count() })
        .Where(p => p.Cnt == 0 || p.Cnt % 2 != 0)
        .Select(p => p.Id);

谢谢你但在"t.id == p"和".Count()"应该改为".Count"时它给我错误。你能帮我看一下这个问题吗? - Rezoan
已修复。但如果您不理解此代码,我不建议使用它。 - Keith Payne

2

顺便提一下,从性能方面来说,如果您创建一个哈希映射将每个ID映射到其计数,然后在循环中搜索它,您将获得更好的性能。

现在您有一个O(n*m)算法,它可以被简化为O(n+m)

// create a map (id -> count), O(m) operation
var dictionary = new Dictionary<string, int>();
foreach (var p in tem)
{
    var counter = 0;
    dictionary.TryGetValue(p.id, out counter);
    counter++;
    dictionary[p.id] = counter;
}

// search the map, O(n) operation
var results = new HashSet<string>();
foreach (var p in pr)
{
    var counter = 0;
    dictionary.TryGetValue(p.id, out counter);
    if (counter == 0 || counter % 2 != 0)
        results.Add(p.id);
}

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