0

I am using the ternary operator but it has big performance inefficiencies is there an equivalent solution to solve the in-efficiency?

Given we have two lists and we wish to select from one using linq:

var myList1 = new List<string>();
var myList2 = new List<string>();

var result = 
      myList1.Select(x => new {
      Id = x,
      Count = myList2.Count(y => y == x) == 0 ? "Not Found" 
                                              : myList2.Count(y => y == x).ToString()
      });

Now with the ternary operator ?: I have shown here the linq expression will check if the count is 0 first and display "Not Found" else it will run the linq count again and show the result. My point is that it will be running the linq query twice when effectively it only needs to store the value and use it again in the else. This seems hugely in-efficient if the linq query was somewhat larger and more complex.

I know the ternary operator should only be used for simple equations e.g. i > 1 ? true : false but what is an alternative to have this within a linq query as I cannot store the value first to use again.

Update:

This is a theoretical question regarding the ternary operator given that it needs to run the same equation twice if the condition applies. Too in-efficient to use when the equation is large and complex ?

James Dev
  • 2,979
  • 1
  • 11
  • 16

3 Answers3

13

I cannot store the value first to use again

Why not? You sure can.

var result = myList1.Select(x => {
    var count = myList2.Count(y => y == x);
    return new {
        Id = x,
        Count = count == 0 ? "Not Found" : count.ToString();
    };
});
Lucas Trzesniewski
  • 50,214
  • 11
  • 107
  • 158
7

You can also do this using query syntax taking advantage of let clause:

var result = from e in myList1
             let count = myList2.Count(y => y == e)
             select new { Count = count == 0 ? "Not Found" : count.ToString()};
ocuenca
  • 38,548
  • 11
  • 89
  • 102
  • @JamesDev This is indeed a more general approach because it's applicable also to `IQueryable`s. But for `IEnumerable`s the other answer is a bit more efficient because it avoids intermediate projection. I upvoted both :) – Ivan Stoev Apr 01 '16 at 14:31
2

You can keep the count result in a variable, so you don't count 2 times for each row in myList1. Code:

var myList1 = new List<string>();
var myList2 = new List<string>();
int counter = 0;
var result = 
      myList1.Select(x => new {
          Id = x
          Count = (counter = myList2.Count(y => y == x)) == 0 ? "Not Found" : counter.ToString()
      });
Alexandru Chichinete
  • 1,166
  • 12
  • 23