Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>I have to admit, I dont really see a major drawback in your class design so far. Of course I dont have any insight in the greater picture and how your game is designed, since this is only a little section of it. </p> <p>However, you said it is the <code>GetCompletePlayerStats</code> that you dont really like. I had to read it several times to understand what you are trying to do here. If I saw that right, you just want to return a <code>PlayerStat</code> object corresponding to each given <code>Stat</code> object. I guess <code>Stat</code> has an <code>Id</code> field (you are using it in your method) to compare two of them for semantic equality.</p> <p>Given, that I made the right assumptions so far (unfortunately, you didnt provide much info), the method can be simplified to something like:</p> <pre><code>public virtual IEnumerable&lt;PlayerStat&gt; GetCompletePlayerStats(IEnumerable&lt;Stat&gt; stats) { foreach(Stat stat in stats) yield return PlayerStats.FirstOrDefault(s =&gt; stat.Id == s.PlayerStatistic.Id) ?? new PlayerStat() {PlayerStatistic = stat, XP = 0}; yield break; } </code></pre> <p>This method here doesnt require a <code>IQueryable</code> but rather a <code>IEnumerable</code> to iterate over via a <code>foreach</code> loop, and yield out the corresponding <code>PlayerStats</code> object if there is one, or create a new one with XP set to 0 otherwise (The null-coalescing operator <code>??</code> is very useful in those cases).</p> <p>Hope that helps!</p>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. COYeah, that'd work, although I have some gripes with it: firstly, calling FirstOrDefault() in a loop is effectively doing a nested-loop join (one explicit loop and another loop inside FirstOrDefault) which has really bad performance with larger sets. For a small number of stats this won't matter, but I was bitten by this kind of traps too many times that I just try to avoid them whenever I can. Secondly, it gives out a lazy enumerable which will be re-evaluated on each call, which might not be what you want. And thirdly, the yield break as the last statement in the method is redundant.
      singulars
    2. CO@Avish: Youre right, the `yield break;` is indeed redundant. But I dont really agree with you about the lazy enumerable thing: You say it may not be what the op wants, but why can you assume creating a list is what the op wants? We dont have any info about that. If we work on large data sets (as you said), a lazy enum may be much more appropriate if he only enumerates the results once. If he wants to reuse the resulting set, he can still call it like: `GetCompletePlayerStats(stats).ToList()`. It is more flexible than just returning a `IList<>`, it assumes something the caller might not want.
      singulars
    3. CO@Avish: Your solution has a better growth rate: Creating the dictionary takes O(m) time, but afterwards every `ContainsKey` call is in O(1). So the overall method is in O(m + n), whereas my solution takes a much worse O(m*n). However I dont believe we are working on sufficiently large datasets to justify this in the first place. What you are doing here is premature optimization. With small datasets my algorithm may even be faster (didnt test it - just a speculation). However, I want to say: it is generally better to optimize with a profiler *afterwards* if any performance problems occur...
      singulars
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload