Files
TextParser/TextParser/Data/DataSetManipulatorBase.cs

154 lines
5.6 KiB
C#

using Parsing.Data;
namespace Parsing.Data;
public class SearchResult<TIndexType>
{
public SearchResult(IDataIndex<TIndexType> dataIndex)
{
this.DataIndex = dataIndex;
}
public IDataIndex<TIndexType>? DataIndex { get; set; }
}
public class DirectionalSearchResult<TIndexType> : SearchResult<TIndexType>
{
public DirectionalSearchResult(IDataIndex<TIndexType> dataIndex, Direction direction, int length): base(dataIndex)
{
this.Direction = direction;
this.Length = length;
}
public Direction Direction { get; set; }
public int Length { get; set; }
}
public abstract class DataSetManipulatorBase<TCollectedType, TDataType, TIndexType> where TDataType : IEquatable<TDataType>
{
protected IDataSetIndexer<TDataType, TIndexType> indexer;
protected List<TCollectedType> dataSet;
public DataSetManipulatorBase(List<TCollectedType> dataSet, IDataSetIndexer<TDataType, TIndexType> indexer)
{
this.indexer = indexer;
this.dataSet = dataSet;
}
// we do not know how to iterate a specific data set exactly, the implementation has to take care of validating directional input
protected abstract Direction ValidDirections();
protected void ValidateDirection(Direction d)
{
var allValidDirections = this.ValidDirections();
var isValid = ((d | allValidDirections) == allValidDirections) && ((d & allValidDirections) > 0);
if (!isValid)
{
throw new ArgumentException("Invalid search direction provided for given data set!");
}
}
protected List<Direction> SimplifyDirections(Direction d)
{
this.ValidateDirection(d);
var allDirections = DirectionProvider.GetAllDirections();
var singleDirections = new List<Direction>();
foreach (Direction direction in allDirections)
{
if ((direction & d) > 0)
{
singleDirections.Add(direction);
}
}
return singleDirections;
}
public List<Direction> GetValidDirectionList(Direction d)
{
return SimplifyDirections(this.ValidDirections());
}
// we do not know how to iterate a specific data set exactly, the implementation has to take care of ending traversal in any direction
public abstract bool IsValidIndex(IDataIndex<TIndexType> queryPosition);
// we do not know how to iterate a specific data set exactly, the implementation has to take care of traversing the set
public abstract IDataIndex<TIndexType> Move(IDataIndex<TIndexType> currentPosition, Direction direction);
public List<IDataIndex<TIndexType>> GetNeighborIndices(IDataIndex<TIndexType> currentPosition, Direction directions)
{
var singleDirections = this.SimplifyDirections(directions);
var neighbors = new List<IDataIndex<TIndexType>>();
foreach (var direction in singleDirections)
{
var newPosition = this.Move(currentPosition, direction);
if (this.IsValidIndex(newPosition))
{
neighbors.Add(newPosition);
}
}
return neighbors;
}
// we do not know how to iterate a specific data set exactly, but we only need to find specific items to be able to continue with any other algorithm
public abstract List<SearchResult<TIndexType>> FindInSet(TDataType data);
public List<DirectionalSearchResult<TIndexType>> FindAtPosition(IDataIndex<TIndexType> currentPosition, List<TDataType> data)
{
return this.FindAtPosition(currentPosition, data, this.ValidDirections());
}
public List<DirectionalSearchResult<TIndexType>> FindAtPosition(IDataIndex<TIndexType> currentPosition, List<TDataType> data, Direction directions)
{
var results = new List<DirectionalSearchResult<TIndexType>>();
var givenDirections = this.SimplifyDirections(directions);
if (EqualityComparer<TDataType>.Default.Equals(this.indexer.Get(this.dataSet, currentPosition), data[0]))
{
// found valid search start point, now validate each given direction
foreach (var direction in givenDirections)
{
int searchIndex = 1;
var searchPosition = this.Move(currentPosition, direction); ;
while (searchIndex < data.Count && this.IsValidIndex(searchPosition)
&& EqualityComparer<TDataType>.Default.Equals(this.indexer.Get(this.dataSet, searchPosition), data[searchIndex]))
{
searchPosition = this.Move(searchPosition, direction);
searchIndex++;
}
if (searchIndex == data.Count)
{
var result = new DirectionalSearchResult<TIndexType>(currentPosition, direction, searchIndex);
results.Add(result);
}
}
}
return results;
}
public List<DirectionalSearchResult<TIndexType>> FindInSet(List<TDataType> data, Direction directions)
{
var result = new List<DirectionalSearchResult<TIndexType>>();
// find valid starting points in set and perform search from there
var startingPoints = this.FindInSet(data[0]);
foreach (var startingPoint in startingPoints)
{
foreach (var results in this.FindAtPosition(startingPoint.DataIndex, data, directions))
{
result.AddRange(results);
}
}
return result;
}
public List<DirectionalSearchResult<TIndexType>> FindInSet(List<TDataType> data)
{
return this.FindInSet(data, this.ValidDirections());
}
}