2010-10-08 67 views
13

我有一個叫Questions的課。這Questions有屬性QuestionIDQuestionAnswer。在foreach中遍歷這個List of Question,我必須找到.QuestionID = 12。如果我找到.QuestionID = 12,那麼我必須立即爲.QuestionID = 14分配一個值.QuestionAnswer = "SomeText"使用LINQ,如何從列表中找到具有給定屬性值的對象?

我不想再次在.QuestionId = 12' to find .QuestionID = 14`內迭代。

有沒有什麼辦法可以直接使用LINQ的.QuestionID = 14 ?.

例如:

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

爲清楚起見,我相信這個問題是問爲避免明確寫在另一個'foreach'循環機制'if'語句,並不完全消除循環。所有涉及'Any()'和'FirstOrDefault()'的回答都有效地隱藏了它們各自實現中的第二個'foreach'。 – 2013-07-03 00:00:07

回答

17

我認爲你在尋找這樣的事情。如果我有一個時刻,我會把它翻譯成VB,但我認爲你可以關注。

if (_mQuestions.Any(q => q.QuestionID == 12)) 
{ 
    Question question14 = _mQuestions.FirstOrDefault(q => q.QuestionID == 14); 
    if (question14 != null) 
     question14.QuestionAnswer = "Some Text"; 
} 
+21

請不要鼓勵人們將完美的代碼翻譯成VB。 :) – 2010-10-10 14:54:00

+6

ROFL。我*討厭* VB – 5arx 2014-02-18 02:10:34

+3

可能會更糟糕,我只是盯着最近編寫的VB.net應用程序,它是用VB6語言編寫的。 2015-02-12 16:01:46

1

不幸的是,你的數據結構(List)要求您再次搜索,找到Question-14一旦Question-12被發現。如果您的Question列表按ID排序,則可以進行一些改進,但通常無法通過僅知道元素屬性的值直接訪問ListArray的元素。

適用於您的問題的數據結構是Dictionary,因爲它允許通過某個值對對象進行索引,並且可以高效地直接訪問這些對象,而無需遍歷整個集合。

您可以通過調用ToDictionary()擴展方法隱蔽您的列表使用LINQ的字典:

IDictionary<Question> questions = _mQuestions.ToDictionary(q => q.id); 

這將使用Question對象爲重點的ID,和對象作爲值。然後在你的代碼,你可以做到以下幾點:

if (questions.ContainsKey(12) && questions.ContainsKey(14)) 
{ 
    questions[14].QuestionAnswer = "Some Text"; 
} 

注意ContainsKey和索引(運營商[])都在固定時間內執行。

+0

不錯的解決方案!請注意,您必須確保該ID在此情況下是唯一的,或者。ToDictionary()將失敗。 – 2013-07-02 20:05:33

0

請注意,我認爲它比其他樣本稍微羅嗦一些,但我設法只用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 
0

使用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"; 
} 
相關問題