4

At the moment I use List<int> ints = tuple.Item2.Select(s => s.Value).ToList() but this looks inefficient when tuple.Item2 has 1000's of items. Any better way to achieve this? except using a for loop.

Jack
  • 7,433
  • 22
  • 63
  • 107

2 Answers2

7

The built-in way to convert each element in one List<T1> and store the result in another List<T2> is List<T1>.ConvertAll.

List<int> ints = tuple.Item2.ConvertAll(s => s.Value);

Unlike .Select(...).ToList() or .Cast(...).ToList(), this method knows the list size in advance, and prevents unnecessary reallocations that .ToList() cannot avoid.

For this to work, tuple.Item2 must really be a List<int?>. It's not an extension method, it cannot work on the generic IEnumerable<int?> interface.

  • It could be that `s => s.GetValueOrDefault()` is faster than just `s => s.Value`. This may seem surprising, but the reason is that `.GetValueOrDefault()` always and unconditionally exposes the backing field (`value`), while the `.Value` property first checks the Boolean field (`hasValue`) to see if it is true or false, and only then exposes that backing field (or throws if `hasValue` was false). The `Nullable<>` struct ensures that the backing field always has its default value in the case where we are modeling a "null", so that is why the behavior of `.GetValueOrDefault()` is safe. – Jeppe Stig Nielsen Apr 16 '22 at 08:39
  • You can also write it as `s => s ?? 0`. – Jeppe Stig Nielsen Apr 16 '22 at 08:46
2

you can simply use Linq Cast<> to achieve this .

List<int> ints = tuple.Item2.Cast<int>();

but if an element cannot be cast to type TResult, this method will throw an exception.you have to consider catching exception.

Behnam Esmaili
  • 5,835
  • 6
  • 32
  • 63
  • 2
    +1 but what about efficiency? You cannot do better than O(n) with cast anyway, I think. And you have to do `.Where(x => x.HasValue)` to check nulls – Roman Pekar Dec 06 '12 at 06:38
  • 2
    You still need a `ToList()` on the end. – Mike Zboray Dec 06 '12 at 06:39
  • 1
    Also this is slower than the original code by a factor of 3 for 200000 items. – Mike Zboray Dec 06 '12 at 06:39
  • @mikez: Really? It looks better than original. I assume built in extension method would be faster. I will test this. – Jack Dec 06 '12 at 06:41
  • @RomanPekar & mike you are right.but i have suggested the way to deceive some one it is efficient :) – Behnam Esmaili Dec 06 '12 at 06:41
  • @BehnamEsmaili: Deceiving is not what I expected but thanks :) – Jack Dec 06 '12 at 06:42
  • @Jack i was just kidding.you'r code will be even more efficient if you put it inside try - catch.if you don't believe me check this : http://stackoverflow.com/questions/8928403/try-catch-speeding-up-my-code\ – Behnam Esmaili Dec 06 '12 at 06:43