O' LINQ-fu masters, please help.
I have a requirement where I have to add items into a List(Of T) (let's call it Target) from an IEnumerable(Of T) (let's call it Source) using Target.AddRange() in VB.NET.
Target.AddRange(Source.TakeWhie(Function(X, Index) ?))
The ? part is a tricky condition that is something like: As long as the as yet unenumerated count is not equal to what is needed to fill the list to the minimum required then randomly decide if the current item should be taken, otherwise take the item. Somethig like...
Source.Count() - Index = _minimum_required - _curr_count_of_items_taken _
OrElse GetRandomNumberBetween1And100() <= _probability_this_item_is_taken
' _minimum_required and _probability_this_item_is_taken are constants
The confounding part is that _curr_count_of_items_taken needs to be incremented each time the TakeWhile statement is satisfied. How would I go about doing that?
I'm also open to a solution that uses any other LINQ methods (Aggregate, Where, etc.) instead of TakeWhile.
If all else fails then I will go back to using a good old for-loop =)
But hoping there is a LINQ solution. Thanks in advance for any suggestions.
EDIT: Good old for-loop version as requested:
Dim _source_total As Integer = Source.Count()
For _index As Integer = 0 To _source_total - 1
If _source_total - _index = MinimumRows - Target.Count _
OrElse NumberGenerator.GetRandomNumberBetween1And100 <= _possibility_item_is_taken Then
Target.Add(Source(_index))
End If
Next
EDITDIT: David's no-side-effects answer comes closes to what I need while staying readable. Maybe he's the only one who could understand my poorly communicated pseudo-code =). The OrderBy(GetRandomNumber) is brilliant in hindsight. I just need to change the Take(3) part to Take(MinimumRequiredPlusAnOptionalRandomAmountExtra) and drop the OrderBy and Select at the end. Thanks to the rest for suggestions.