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.

7
  • ^ Konstantin, it is - however its a real good question. @ Jack - This is better for "Code Review" Commented Dec 6, 2012 at 6:33
  • Besides your code does not reflect the situation when s.HasValue == false... Commented Dec 6, 2012 at 6:33
  • Are you guaranteed that all objects will have a value? Commented Dec 6, 2012 at 6:34
  • @ Maurice - hes not. CODE REVIEW TOPIC NOT STACK !!! Commented Dec 6, 2012 at 6:34
  • @Maurico: Yes. Next question from Konstanin would be so why use List<int?>. Answer is I have to because it is returned from 3rd party lib. Commented Dec 6, 2012 at 6:35

2 Answers 2

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.

Sign up to request clarification or add additional context in comments.

2 Comments

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.
You can also write it as s => s ?? 0.
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.

7 Comments

+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
You still need a ToList() on the end.
Also this is slower than the original code by a factor of 3 for 200000 items.
@mikez: Really? It looks better than original. I assume built in extension method would be faster. I will test this.
@RomanPekar & mike you are right.but i have suggested the way to deceive some one it is efficient :)
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.