|
using System;
using System.Collections.Generic;
namespace IEnumerableCS
{
/// <summary>
/// An Enumerator for a 2D array of double(,), enumerates horizontally (by row)
/// </summary>
/// <remarks></remarks>
public class HorizontalMatrixEnumerator : IEnumerator<double>
{
private double[,] _matrix;
private int _colIndex;
private int _rowIndex;
private double _curItem;
private int _lastCol;
private int _lastRow;
/// <summary>
/// Creates the Enumerator using the supplied 2D array of double and initialises the fields
/// </summary>
/// <param name="matrix">The 2D array of double(,) to be enumerated</param>
/// <remarks></remarks>
public HorizontalMatrixEnumerator(double[,] matrix)
{
this._matrix = matrix;
this._colIndex = -1;
this._rowIndex = 0;
this._curItem = double.NaN;
this._lastCol = matrix.GetUpperBound(1);
this._lastRow = matrix.GetUpperBound(0);
}
/// <summary>
/// Returns the current item of the array during an enumeration
/// </summary>
/// <value>The current item of the array during an enumeration</value>
/// <returns>A double representing the current item of the array during an enumeration</returns>
/// <exception cref="InvalidOperationException">This exception is thrown if an attempt to access Current is made before MoveNext has been called - applies either immediately after object creation or after a call to <see cref="Reset">Reset()</see></exception>
/// <remarks>Does not cause the position to change, repeated calls to Current will return the same value, use MoveNext to change position</remarks>
public double Current
{
get
{
//If _curItem is NaN then throw an exception
//this would happen if Current was referenced before MoveNext had been called
if (double.IsNaN(this._curItem))
{
throw new InvalidOperationException();
}
return this._curItem;
}
}
/// <summary>
/// [Use Current instead] Returns the current item of the array during an enumeration
/// </summary>
/// <value>[Use Current instead] The current item of the array during an enumeration</value>
/// <returns>[Use Current instead] A double representing the current item of the array during an enumeration</returns>
/// <remarks>[Use Current instead] Does not cause the position to change, repeated calls to Current will return the same value, use MoveNext to change position</remarks>
object System.Collections.IEnumerator.Current
{
get { return this.Current; }
}
/// <summary>
/// Moves to the next position in the array
/// </summary>
/// <returns><code>False</code> if the end of the array was reached after the porevious call to MoveNext, <code>True</code> otherwise</returns>
/// <remarks></remarks>
public bool MoveNext()
{
//Ensure we are not already at the bottom right corner of the array
if (this._colIndex == this._lastCol & this._rowIndex == this._lastRow)
{
//Return False immediately
return false;
}
//Check if we are at the end of a row
if (this._colIndex == this._lastCol)
{
//Move to the next row, starting at column 0
this._colIndex = 0;
this._rowIndex += 1;
}
else
{
//Or just move to the next column in the row
this._colIndex += 1;
}
//Set the value of _curItem to represent the new position in the array
this._curItem = this._matrix[this._rowIndex, this._colIndex];
//Returns true only if we have successfully changed position in the array
return true;
}
/// <summary>
/// Resets the Enumerator object to the state as immediately after creation
/// </summary>
/// <remarks>A call to <see cref="Current">Current</see> after Reset will throw an exception, a call to <see cref="MoveNext">MoveNext</see> must be made first</remarks>
public void Reset()
{
this._colIndex = -1;
this._rowIndex = 0;
this._curItem = double.NaN;
}
#region "IDisposable Support"
// To detect redundant calls
private bool disposedValue;
// IDisposable
protected virtual void Dispose(bool disposing)
{
if (!this.disposedValue)
{
if (disposing)
{
// None
}
}
this.disposedValue = true;
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
#endregion
}
/// <summary>
/// An Enumerator for a 2D array of double(,), enumerates vertically (by column)
/// </summary>
/// <remarks></remarks>
public class VerticalMatrixEnumerator : IEnumerator<double>
{
private double[,] _matrix;
private int _colIndex;
private int _rowIndex;
private double _curItem;
private int _lastCol;
private int _lastRow;
/// <summary>
/// Creates the Enumerator using the supplied 2D array of double and initialises the fields
/// </summary>
/// <param name="matrix">The 2D array of double(,) to be enumerated</param>
/// <remarks></remarks>
public VerticalMatrixEnumerator(double[,] matrix)
{
this._matrix = matrix;
this._colIndex = 0;
this._rowIndex = -1;
this._curItem = double.NaN;
this._lastCol = matrix.GetUpperBound(1);
this._lastRow = matrix.GetUpperBound(0);
}
/// <summary>
/// Returns the current item of the array during an enumeration
/// </summary>
/// <value>The current item of the array during an enumeration</value>
/// <returns>A double representing the current item of the array during an enumeration</returns>
/// <exception cref="InvalidOperationException">This exception is thrown if an attempt to access Current is made before MoveNext has been called - applies either immediately after object creation or after a call to <see cref="Reset">Reset()</see></exception>
/// <remarks>Does not cause the position to change, repeated calls to Current will return the same value, use MoveNext to change position</remarks>
public double Current
{
get
{
//If _curItem is null then throw an exception
//this would happen if Current was referenced before MoveNext had been called
if (double.IsNaN(this._curItem))
{
throw new InvalidOperationException();
}
return this._curItem;
}
}
/// <summary>
/// [Use Current instead] Returns the current item of the array during an enumeration
/// </summary>
/// <value>[Use Current instead] The current item of the array during an enumeration</value>
/// <returns>[Use Current instead] A double representing the current item of the array during an enumeration</returns>
/// <remarks>[Use Current instead] Does not cause the position to change, repeated calls to Current will return the same value, use MoveNext to change position</remarks>
object System.Collections.IEnumerator.Current
{
get { return this.Current; }
}
/// <summary>
/// Moves to the next position in the array
/// </summary>
/// <returns><code>False</code> if the end of the array was reached after the porevious call to MoveNext, <code>True</code> otherwise</returns>
/// <remarks></remarks>
public bool MoveNext()
{
//Ensure we are not already at the bottom right corner of the array
if (this._colIndex == this._lastCol & this._rowIndex == this._lastRow)
{
//Return False immediately
return false;
}
//Check if we are at the end of a row
if (this._rowIndex == this._lastRow)
{
//Move to the next column, starting at row 0
this._rowIndex = 0;
this._colIndex += 1;
}
else
{
//Or just move to the next column in the row
this._rowIndex += 1;
}
//Set the value of _curItem to represent the new position in the array
this._curItem = this._matrix[this._rowIndex, this._colIndex];
//Returns true only if we have successfully changed position in the array
return true;
}
/// <summary>
/// Resets the Enumerator object to the state as immediately after creation
/// </summary>
/// <remarks>A call to <see cref="Current">Current</see> after Reset will throw an exception, a call to <see cref="MoveNext">MoveNext</see> must be made first</remarks>
public void Reset()
{
this._colIndex = 0;
this._rowIndex = -1;
this._curItem = double.NaN;
}
#region "IDisposable Support"
// To detect redundant calls
private bool disposedValue;
// IDisposable
protected virtual void Dispose(bool disposing)
{
if (!this.disposedValue)
{
if (disposing)
{
// None
}
}
this.disposedValue = true;
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
#endregion
}
}
|
By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.
If a file you wish to view isn't highlighted, and is a text file (not binary), please
let us know and we'll add colourisation support for it.