Используя LINQ, как мне найти объект с заданным значением свойства из списка?
У меня есть класс под названием Questions
. Этот Questions
имеет свойства QuestionID
и QuestionAnswer
. Повторяя это через List of Question
в foreach, я должен найти .QuestionID = 12
. Если я нахожу .QuestionID = 12
, тогда я должен немедленно присвоить значение .QuestionAnswer = "SomeText"
.QuestionID = 14
.
Я не хочу снова повторять внутри .QuestionId = 12' to find
.QuestionID = 14`.
Можно ли перейти непосредственно к .QuestionID = 14
с помощью LINQ?.
Например:
For Each mQuestion As Question In _mQuestions
If mQuestion.QuestionId = 12 Then
'Find mQuestion.QuestionID= 14 and insert Somtext to
'mQuestion.QuestionAnswer="SomeText"
End IF
Next
Ответы
Ответ 1
Я думаю, вы ищете что-то вроде этого. Если у меня есть момент, я переведу его на VB, но я думаю, что вы можете следовать.
if (_mQuestions.Any(q => q.QuestionID == 12))
{
Question question14 = _mQuestions.FirstOrDefault(q => q.QuestionID == 14);
if (question14 != null)
question14.QuestionAnswer = "Some Text";
}
Ответ 2
К сожалению, ваша структура данных (List
) требует повторного поиска, чтобы найти Question-14
один раз Question-12
. Если ваш список Question
сортируется по идентификатору, то могут быть сделаны некоторые улучшения, но, как правило, нет способа прямого доступа к элементу List
или Array
, только зная значения свойства element.
Структура данных, применимая к вашей проблеме, это Dictionary
, поскольку она позволяет индексировать объекты через какое-то значение, а также эффективный прямой доступ к этим объектам без необходимости итерации по всей коллекции.
Вы можете скрывать свой список в словаре с помощью Linq, вызывая метод расширения ToDictionary():
IDictionary<Question> questions = _mQuestions.ToDictionary(q => q.id);
В качестве ключа используется идентификатор объекта Question
, а объект - как значение. Затем в вашем коде вы можете сделать следующее:
if (questions.ContainsKey(12) && questions.ContainsKey(14))
{
questions[14].QuestionAnswer = "Some Text";
}
Обратите внимание, что ContainsKey
и индекс (оператор []) выполняются в постоянное время.
Ответ 3
Имейте в виду, я беру на себя это немного более многословие, чем другие образцы, но мне удалось это сделать только с LINQ. (Следите за комментариями в стиле C ниже!)
Private Shared Sub Main(args As String())
Dim questions As List(Of Question) = GetQuestions()
Dim question As Question = ( _
Where q.ID = 14 AndAlso _
questions.Exists(Function(p) p.ID = 12)).FirstOrDefault()
If question IsNot Nothing Then
question.Answer = "Some Text"
End If
End Sub
// Build the collection of questions! We keep this simple.
Private Shared Function GetQuestions() As List(Of Question)
Dim questions As New List(Of Question)()
questions.Add(New Question(12, "foo"))
questions.Add(New Question(14, "bar"))
Return questions
End Function
// You've already got this class. This one is just my version.
Public Class Question
Public Sub New(id As Integer, answer As String)
Me.ID = id
Me.Answer = answer
End Sub
Public Property ID() As Integer
Get
Return m_ID
End Get
Set
m_ID = Value
End Set
End Property
Private m_ID As Integer
Public Property Answer() As String
Get
Return m_Answer
End Get
Set
m_Answer = Value
End Set
End Property
Private m_Answer As String
End Class
Ответ 4
Использование LINQ:
var listOfQ = new List<Question>();
// populate the list of Question somehow...
var q14 = listOfQ.FirstOrDefault(q => q.QuestionID == 14);
if (listOfQ.Any(q => q.QuestionID == 12) && q14 != null)
{
q14.QuestionAnswer = "SomeText";
}