Replace boolean OrderBy with DeferBy

orderby consumes the entire input enumerable in 'sorting' the list;
since we don't care about the order besides a yes/no, just manage the
yield order ourselves.

don't bother using this method more than the spot it's in; was a fun
exercise but other spots are set up for easier debugging
(overall flow is where->deferby->yield), could make things easier to
read but meh
This commit is contained in:
Kurt 2018-07-17 16:28:42 -07:00
parent e4aa16f396
commit fe7fea877b
2 changed files with 30 additions and 2 deletions

View file

@ -1,4 +1,5 @@
using System.Collections.Generic; using System;
using System.Collections.Generic;
using System.Linq; using System.Linq;
using static PKHeX.Core.Legal; using static PKHeX.Core.Legal;
@ -420,5 +421,32 @@ namespace PKHeX.Core
var tr = t.GetOT(pkm.Language); var tr = t.GetOT(pkm.Language);
return ot == tr; return ot == tr;
} }
/// <summary>
/// Filters a sequence of values based on a predicate.
/// Any elements that match the predicate are yielded after those that did not match, in the same order they were observed.
/// </summary>
/// <remarks>
/// <see cref="Enumerable"/> OrderBy consumes the entire list when reordering elements, instead of instantly yielding best matches.
/// https://referencesource.microsoft.com/#System.Core/System/Linq/Enumerable.cs,ffb8de6aefac77cc</remarks>
/// <typeparam name="T">The type of the elements of source.</typeparam>
/// <param name="source">A sequence of values to reorder.</param>
/// <param name="predicate">A function to test each element for a condition.</param>
/// <returns>An <see cref="IEnumerable{T}"/> that contains elements from the input, with non-deferred results first.</returns>
internal static IEnumerable<T> DeferByBoolean<T>(this IEnumerable<T> source, Func<T, bool> predicate)
{
var deferred = new List<T>();
foreach (var x in source)
{
if (predicate(x))
{
deferred.Add(x);
continue;
}
yield return x;
}
foreach (var d in deferred)
yield return d;
}
} }
} }

View file

@ -64,7 +64,7 @@ namespace PKHeX.Core
bool IsHidden = pkm.AbilityNumber == 4; // hidden Ability bool IsHidden = pkm.AbilityNumber == 4; // hidden Ability
int species = pkm.Species; int species = pkm.Species;
return s.OrderBy(slot => slot.IsDeferred(species, pkm, IsSafariBall, IsSportBall, IsHidden)); // non-deferred first return s.DeferByBoolean(slot => slot.IsDeferred(species, pkm, IsSafariBall, IsSportBall, IsHidden)); // non-deferred first
} }
public static bool IsDeferred3(this EncounterSlot slot, int currentSpecies, PKM pkm, bool IsSafariBall) public static bool IsDeferred3(this EncounterSlot slot, int currentSpecies, PKM pkm, bool IsSafariBall)
{ {