Skip to content

Commit

Permalink
Grid fixes and EnumerableUtils improvements
Browse files Browse the repository at this point in the history
* Remove GridLine class
* Add EnumerableUtils.WhereOrdered() and .WhereOrderedBy()
  • Loading branch information
Nixill committed Dec 9, 2022
1 parent d951ef3 commit 9985443
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 101 deletions.
2 changes: 1 addition & 1 deletion CSharp.Nixill/src/Grid/CSVParser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ public static Grid<string> EnumerableToGrid(IEnumerable<char> input) {
/// </summary>
/// <param name="input">The grid to output.</param>
public static IEnumerable<string> GridToStringEnumerable<T>(IGrid<T> input) {
foreach (GridLine<T> line in input) {
foreach (IEnumerable<T> line in input) {
StringBuilder ret = new StringBuilder();
foreach (T obj in line) {
ret.Append("," + CSVEscape(obj?.ToString() ?? ""));
Expand Down
103 changes: 3 additions & 100 deletions CSharp.Nixill/src/Grid/Grid.cs
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ public T this[string gr] {
public IEnumerable<IEnumerable<T>> Rows {
get {
for (int i = 0; i < Height; i++) {
yield return GetRow(i);
yield return RowEnumerable(i);
}
}
}
Expand Down Expand Up @@ -176,7 +176,7 @@ public bool Contains(T item) {
}

public IList<T> GetColumn(int index) {
return new GridLine<T>(this, true, index);
return new List<T>(ColumnEnumerable(index));
}

public IEnumerator<IEnumerable<T>> GetColumnEnumerator() => Columns.GetEnumerator();
Expand All @@ -185,7 +185,7 @@ public IList<T> GetColumn(int index) {
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();

public IList<T> GetRow(int index) {
return new GridLine<T>(this, false, index);
return new List<T>(RowEnumerable(index));
}

public GridReference IndexOf(T item) {
Expand Down Expand Up @@ -259,101 +259,4 @@ public void RemoveRowAt(int row) {
BackingList.RemoveAt(row);
}
}

/// <summary>
/// One line - either a whole row or column - of a grid.
///
/// The constructed GridLine is a window to a static point. GridLines to
/// invalid rows or columns (higher than the range) can be constructed,
/// but attempts to retrieve data from them will cause exceptions. A
/// GridLine won't move with the actual line it initially references,
/// i.e. a GridLine for column 2 will always point to whatever happens
/// to be the column in that position. However, the size of the line
/// will change with the size of that axis of the grid.
///
/// A GridLine's structure cannot be modified from the GridLine class,
/// but will reflect any changes made from the Grid class. Individual
/// elements are likewise synced but can be changed from either class.
/// </summary>
public class GridLine<T> : IList<T> {
public IGrid<T> ParentGrid { get; internal set; }
public bool IsColumn { get; internal set; }
public int Index { get; internal set; }

public T this[int index] {
get {
if (!IsColumn) return ParentGrid[Index, index];
else return ParentGrid[index, Index];
}
set {
if (!IsColumn) ParentGrid[Index, index] = value;
else ParentGrid[index, Index] = value;
}
}

public int Count => IsColumn ? ParentGrid.Height : ParentGrid.Width;

public bool IsReadOnly => false;

public GridLine(IGrid<T> parent, bool isColumn, int index) {
ParentGrid = parent;
IsColumn = isColumn;
Index = index;
}

public void Add(T item) {
throw new System.NotSupportedException();
}

public void Clear() {
throw new System.NotSupportedException();
}

public bool Contains(T item) {
foreach (T itm in this) {
if (object.Equals(itm, item)) return true;
}
return false;
}

public void CopyTo(T[] array, int arrayIndex) {
((List<T>)this).CopyTo(array, arrayIndex);
}

public IEnumerator<T> GetEnumerator() {
int len = Count;
for (int i = 0; i < len; i++) {
yield return this[i];
}
}

public int IndexOf(T item) {
int len = Count;
for (int i = 0; i < len; i++) {
if (object.Equals(item, this[i])) return i;
}
return -1;
}

public void Insert(int index, T item) {
throw new System.NotSupportedException();
}

public bool Remove(T item) {
throw new System.NotSupportedException();
}

public void RemoveAt(int index) {
throw new System.NotSupportedException();
}

IEnumerator IEnumerable.GetEnumerator() {
int len = Count;
for (int i = 0; i < len; i++) {
yield return this[i];
}
}

public static explicit operator List<T>(GridLine<T> input) => new List<T>(input);
}
}
35 changes: 35 additions & 0 deletions CSharp.Nixill/src/Utils/EnumerableUtils.cs
Original file line number Diff line number Diff line change
Expand Up @@ -234,4 +234,39 @@ public static IEnumerable<IEnumerable<TSource>> ChunkWhile<TSource>(this IEnumer
}

public static string FormString(this IEnumerable<char> chars) => new string(chars.ToArray());

public static IEnumerable<TSource> WhereOrderedBy<TSource, TKey>(this IEnumerable<TSource> sequence,
Func<TSource, TKey> mutator, IComparer<TKey> comparer, bool desc = false, bool distinctly = false) {
bool assigned = false;
TKey last = default(TKey);

Func<int, bool> expected;

if (desc)
if (distinctly) expected = (i) => i < 0;
else expected = (i) => i <= 0;
else
if (distinctly) expected = (i) => i > 0;
else expected = (i) => i >= 0;

foreach (TSource item in sequence) {
TKey key = mutator(item);

if ((!assigned) || expected(comparer.Compare(key, last))) {
last = key;
assigned = true;
yield return item;
}
}
}

public static IEnumerable<TSource> WhereOrderedBy<TSource, TKey>(this IEnumerable<TSource> sequence,
Func<TSource, TKey> mutator, bool desc = false, bool distinctly = false)
=> sequence.WhereOrderedBy(mutator, Comparer<TKey>.Default, desc, distinctly);

public static IEnumerable<T> WhereOrdered<T>(this IEnumerable<T> sequence, IComparer<T> comparer, bool desc = false,
bool distinctly = false) => sequence.WhereOrderedBy(x => x, comparer, desc, distinctly);

public static IEnumerable<T> WhereOrdered<T>(this IEnumerable<T> sequence, bool desc = false, bool distinctly = false)
=> sequence.WhereOrderedBy(x => x, Comparer<T>.Default, desc, distinctly);
}

0 comments on commit 9985443

Please sign in to comment.