Add `IEnumerable<bool>.Unanimity` extension

This commit is contained in:
YoshiRulz 2025-06-02 08:47:16 +10:00
parent bb7e5bc02c
commit b4105f9423
No known key found for this signature in database
GPG Key ID: C4DE31C245353FB7
2 changed files with 54 additions and 0 deletions

View File

@ -490,6 +490,42 @@ namespace BizHawk.Common.CollectionExtensions
return removed;
}
/// <inheritdoc cref="Unanimity(ISet{bool})"/>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool? Unanimity(this IEnumerable<bool> lazy)
=> lazy is IReadOnlyCollection<bool> collection
? Unanimity(collection)
: Unanimity(lazy as ISet<bool> ?? lazy.ToHashSet());
/// <inheritdoc cref="Unanimity(ISet{bool})"/>
public static bool? Unanimity(this IReadOnlyCollection<bool> collection)
{
if (collection is bool[] arr) return Unanimity(arr.AsSpan());
if (collection is List<bool> list)
{
return list is [ var first, .. ] && list.IndexOf(!first, index: 1) < 0 ? first : null;
}
var iter = collection.GetEnumerator();
if (!iter.MoveNext()) return null;
var first1 = iter.Current;
while (iter.MoveNext()) if (iter.Current != first1) return null;
return first1;
}
/// <returns>
/// <see langword="true"/> if all <see langword="true"/>,
/// <see langword="false"/> if all <see langword="false"/>,
/// <see langword="true"/> if mixed (or empty)
/// </returns>
public static bool? Unanimity(this ISet<bool> set)
=> set.Contains(false)
? set.Contains(true) ? null : false
: set.Contains(true) ? true : null;
/// <inheritdoc cref="Unanimity(ISet{bool})"/>
public static bool? Unanimity(this ReadOnlySpan<bool> span)
=> span is [ var first, .. ] && !span.Slice(start: 1).Contains(!first) ? first : null;
public static bool IsSortedAsc<T>(this IReadOnlyList<T> list)
where T : IComparable<T>
{

View File

@ -1,5 +1,7 @@
using System.Collections;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Linq;
using BizHawk.Common.CollectionExtensions;
@ -134,5 +136,21 @@ namespace BizHawk.Tests.Common.CollectionExtensions
c.RemoveAll(Predicate);
Assert.AreEqual(2, c.Count, nameof(CE.RemoveAll) + " failed on (ICollection<int> not IList<int>)");
}
[DataRow(new bool[0], null)]
[DataRow(new bool[] { true }, true)]
[DataRow(new bool[] { false }, false)]
[DataRow(new bool[] { true, true }, true)]
[DataRow(new bool[] { false, false }, false)]
[DataRow(new bool[] { true, false }, null)]
[DataRow(new bool[] { false, true }, null)]
[TestMethod]
public void TestUnanimity(bool[] array, bool? expected)
{
Assert.AreEqual(expected, ((ISet<bool>) array.ToHashSet()).Unanimity(), "ISet");
Assert.AreEqual(expected, array.Unanimity(), "Span");
Assert.AreEqual(expected, array.ToList().Unanimity(), "List");
Assert.AreEqual(expected, ImmutableArray.Create(array).Unanimity(), "IROColl not List");
}
}
}