LINQ:按id从对象数组中选择单个值

时间:2022-09-30 20:51:08

Take the following example class:

参加以下示例类:

public class Questions
{
    public Int32 QuestionId { get; set; }
    public String Question { get; set; }
    public String Answer { get; set; }
}

And the following array:

以下数组:

var questionArray = new Questions[]
{
    new Questions {QuestionId = 1, Question = "How old are you?", Answer = "32"},
    new Questions {QuestionId = 2, Question = "What is your name?", Answer = "John"},
    new Questions {QuestionId = 3, Question = "How tall are you?", Answer = "6'"}
};

Using LINQ, I want to get the Answer for a specified QuestionId. For example, if I gave QuestionId 2, the result would be 'John'.

使用LINQ,我想获得指定QuestionId的答案。例如,如果我给了QuestionId 2,结果就是'John'。

I want to be able to pull out the answer to a specific question to populate a separate DTO. ie:

我希望能够得出一个特定问题的答案来填充一个单独的DTO。即:

var person = new PersonDto {Name = <single line LINQ goes here>};

So far I have only managed to get an answer using the following:

到目前为止,我只能使用以下方法获得答案:

foreach (var q in questionArray.Where(q => q.QuestionId == 2))
{
    var answer = q.Answer;
}

Is this possible in 1 line of code?

这可能在一行代码中吗?

2 个解决方案

#1


6  

It is possible using for e.g. Single from Linq, Single will throw exception when there will be more than one answer.

可以使用例如来自Linq的Single,当有多个答案时,Single会抛出异常。

var answer = questionArray.Single(x=>x.QuestionId == 2).Answer;

This answer assumes that there is only one answer to one question (and it is always present). You can add SingleOrDefault and check for null if you are not sure if answer exists. Or you can add Where clause to get more than one answer, like:

这个答案假定一个问题只有一个答案(并且总是存在)。如果您不确定是否存在答案,则可以添加SingleOrDefault并检查null。或者您可以添加Where子句以获得多个答案,例如:

var answers = questionArray.Where(x=>x.QuestionId == 2).Select(x=>x.Answer);

Above snippet will not fail if there is no answer to question and it will return empty sequence for it. You can test it for having a value and run First on it.

如果没有问题的答案,上面的片段不会失败,它将返回空序列。您可以测试它是否有值并在其上运行First。

#2


3  

You are using the Wrong(tm) datatype. For lookups like these, use a Dictionary.

您正在使用Wrong(tm)数据类型。对于这些查找,请使用Dictionary。

public class Question // Class names should be a singular form noun
{
    public int Id { get; set; } // QuestionId is redundant
    public string Question { get; set; }
    public string Answer { get; set; }
}

var questions = new Question[]
{
    new Questions {Id = 1, Question = "How old are you?", Answer = "32"},
    new Questions {Id = 2, Question = "What is your name?", Answer = "John"},
    new Questions {Id = 3, Question = "How tall are you?", Answer = "6'"}
}.ToDictionary(q => q.Id, q => q);

var answerToQuestionNumberTwo = questions[2].Answer;

EDIT: Clarification, the reason a dictionary is "better" here is because it is both more readable and is faster. You want to construct a collection meant for associating a question with a given ID, enabling you to do lookups on question objects to query their properties. This is the raison d'être of the Dictionary data structure and it has a lookup time complexity of O(1) (compared to O(n) of the Where/First/Single LINQ methods).

编辑:澄清,字典在这里“更好”的原因是因为它更具可读性和更快。您希望构建一个用于将问题与给定ID相关联的集合,使您能够对问题对象进行查找以查询其属性。这是Dictionary数据结构的存在理由,它的查找时间复杂度为O(1)(与Where / First / Single LINQ方法的O(n)相比)。

#1


6  

It is possible using for e.g. Single from Linq, Single will throw exception when there will be more than one answer.

可以使用例如来自Linq的Single,当有多个答案时,Single会抛出异常。

var answer = questionArray.Single(x=>x.QuestionId == 2).Answer;

This answer assumes that there is only one answer to one question (and it is always present). You can add SingleOrDefault and check for null if you are not sure if answer exists. Or you can add Where clause to get more than one answer, like:

这个答案假定一个问题只有一个答案(并且总是存在)。如果您不确定是否存在答案,则可以添加SingleOrDefault并检查null。或者您可以添加Where子句以获得多个答案,例如:

var answers = questionArray.Where(x=>x.QuestionId == 2).Select(x=>x.Answer);

Above snippet will not fail if there is no answer to question and it will return empty sequence for it. You can test it for having a value and run First on it.

如果没有问题的答案,上面的片段不会失败,它将返回空序列。您可以测试它是否有值并在其上运行First。

#2


3  

You are using the Wrong(tm) datatype. For lookups like these, use a Dictionary.

您正在使用Wrong(tm)数据类型。对于这些查找,请使用Dictionary。

public class Question // Class names should be a singular form noun
{
    public int Id { get; set; } // QuestionId is redundant
    public string Question { get; set; }
    public string Answer { get; set; }
}

var questions = new Question[]
{
    new Questions {Id = 1, Question = "How old are you?", Answer = "32"},
    new Questions {Id = 2, Question = "What is your name?", Answer = "John"},
    new Questions {Id = 3, Question = "How tall are you?", Answer = "6'"}
}.ToDictionary(q => q.Id, q => q);

var answerToQuestionNumberTwo = questions[2].Answer;

EDIT: Clarification, the reason a dictionary is "better" here is because it is both more readable and is faster. You want to construct a collection meant for associating a question with a given ID, enabling you to do lookups on question objects to query their properties. This is the raison d'être of the Dictionary data structure and it has a lookup time complexity of O(1) (compared to O(n) of the Where/First/Single LINQ methods).

编辑:澄清,字典在这里“更好”的原因是因为它更具可读性和更快。您希望构建一个用于将问题与给定ID相关联的集合,使您能够对问题对象进行查找以查询其属性。这是Dictionary数据结构的存在理由,它的查找时间复杂度为O(1)(与Where / First / Single LINQ方法的O(n)相比)。