【问题标题】:LINQ: Select single value from object array, by idLINQ:从对象数组中选择单个值,按 id
【发布时间】:2015-09-25 08:26:34
【问题描述】:

以下面的类为例:

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

还有以下数组:

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'"}
};

使用 LINQ,我想获取指定 QuestionIdAnswer。例如,如果我给QuestionId 2,则结果将是 'John'。

我希望能够提取特定问题的答案以填充单独的 DTO。即:

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

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

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

这可以在 1 行代码中实现吗?

【问题讨论】:

  • 是的,这是可能的。到目前为止,您尝试过什么?
  • @Dom84 用我试过的代码更新了问题。
  • 所以 QuestionId 在这种情况下不是唯一的吗?那么你决定采用一个特定的元素是什么?
  • @Dom84 QuestionId 始终是唯一的。我已经用更多信息再次更新了这个问题。

标签: c# arrays linq class object


【解决方案1】:

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

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

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

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

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

【讨论】:

  • 您甚至可以在第二个代码示例的后面添加一个 .FirstOrDefault() 。我们可以假设 QuestionId 在 questionArray 中是唯一的
  • @Dbuggy 不确定我们是否可以假设,这就是我建议这种方法的原因。
  • 我不会不同意你的观点。但是,对于需要“我想获得指定 QuestionId 的答案”的 OP 是安全的,恕我直言,对于 questionID,只有一个答案。所以我正在修改我之前的评论,现在声明 FirstOrDefault() 不应在最后使用,但 SingleOrDefault :)
  • @wudzik 正是我需要的! QuestionId 始终是唯一的,我知道它是否存在于 questionArray 中,因此您的第一行代码可以完美运行。
  • @Dbuggy,也喜欢您将 .FirstOrDefault() 添加到第二个代码示例末尾的建议。我在 QuestionId 不存在的地方对此进行了测试,并且效果很好。
【解决方案2】:

您正在使用 Wrong(tm) 数据类型。对于此类查找,请使用字典。

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;

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-01-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-05-20
    • 2023-03-09
    相关资源
    最近更新 更多