Skip to content

Commit 7f7ba29

Browse files
committed
Migrated final classes from 'Collections' namespace.
1 parent 036015e commit 7f7ba29

File tree

3 files changed

+209
-0
lines changed

3 files changed

+209
-0
lines changed
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
using System;
2+
using System.Collections.Generic;
3+
4+
5+
namespace Whathecode.System.Collections.Generic
6+
{
7+
/// <summary>
8+
/// A dictionary which can be used to store values for a set of keys, which are only set the first time they are requested.
9+
/// After the first initialization, next Get() calls will return the cached value.
10+
/// </summary>
11+
/// <typeparam name = "TKey">The type of the key, used to receive values.</typeparam>
12+
/// <typeparam name = "TValue">The type for the stored cached values.</typeparam>
13+
public class CachedDictionary<TKey, TValue>
14+
{
15+
readonly Dictionary<TKey, TValue> _values = new Dictionary<TKey, TValue>();
16+
readonly Func<TKey, TValue> _valueInitializer;
17+
18+
19+
/// <summary>
20+
/// Initialize a new empty CachedDictionary.
21+
/// </summary>
22+
/// <param name = "valueInitializer">The delegate to be called to initialize an uncached value for a given key.</param>
23+
public CachedDictionary( Func<TKey, TValue> valueInitializer )
24+
{
25+
if ( valueInitializer == null )
26+
{
27+
throw new ArgumentNullException( nameof( valueInitializer ) );
28+
}
29+
30+
_valueInitializer = valueInitializer;
31+
}
32+
33+
34+
/// <summary>
35+
/// Get the value for a given key. Initializes the value first when it's not yet initialized.
36+
/// </summary>
37+
/// <param name = "key">The key to get the matching value from.</param>
38+
/// <returns>The value of the given key.</returns>
39+
public TValue this[ TKey key ]
40+
{
41+
get
42+
{
43+
TValue value;
44+
if ( !_values.TryGetValue( key, out value ) )
45+
{
46+
value = _valueInitializer( key );
47+
_values[ key ] = value;
48+
}
49+
50+
return value;
51+
}
52+
}
53+
}
54+
}
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
using System.Collections.Generic;
2+
3+
4+
namespace Whathecode.System.Collections.Generic
5+
{
6+
/// <summary>
7+
/// A list which loops over a list of objects indefinetely when retrieving objects from it.
8+
/// </summary>
9+
/// <typeparam name = "T">The type of objects in the list.</typeparam>
10+
public class LoopList<T>
11+
{
12+
readonly Queue<T> _objects;
13+
14+
15+
/// <summary>
16+
/// Create a new loop list, initialized with a range of objects.
17+
/// </summary>
18+
/// <param name = "range">The range of objects to initialize the list with.</param>
19+
public LoopList( IEnumerable<T> range )
20+
{
21+
_objects = new Queue<T>( range );
22+
}
23+
24+
25+
/// <summary>
26+
/// Get the next item from the list.
27+
/// </summary>
28+
public T Next()
29+
{
30+
T next = _objects.Dequeue();
31+
_objects.Enqueue( next );
32+
return next;
33+
}
34+
35+
/// <summary>
36+
/// Returns an enumerator which only returns all objects once.
37+
/// </summary>
38+
public IEnumerator<T> GetNonLoopedEnumerator()
39+
{
40+
return _objects.GetEnumerator();
41+
}
42+
}
43+
}
Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
5+
6+
namespace Whathecode.System.Collections.Generic
7+
{
8+
/// <summary>
9+
/// A collection of elements organized within a hierarchy.
10+
/// </summary>
11+
/// <typeparam name = "T">The type of the values in the dictionary.</typeparam>
12+
public class Tree<T>
13+
{
14+
public T Value;
15+
16+
/// <summary>
17+
/// The parent to which this tree is connected. Null when this is a root.
18+
/// </summary>
19+
public Tree<T> Parent { get; private set; }
20+
21+
readonly List<Tree<T>> _children = new List<Tree<T>>();
22+
public IEnumerable<Tree<T>> Children
23+
{
24+
get { return _children; }
25+
}
26+
27+
28+
public Tree( T value )
29+
{
30+
Value = value;
31+
}
32+
33+
34+
/// <summary>
35+
/// Adds a full branch to this tree, as specified by an ordered list of values.
36+
/// Existing branches (using the default Equals comparator) remain unchanged.
37+
/// </summary>
38+
/// <param name = "branch">The branch to add, ordered from the first branch after the root of this tree, to the final branch.</param>
39+
/// <returns>The first non-existing node of the branch which got added, or null when node already existed.</returns>
40+
public Tree<T> AddBranch( IEnumerable<T> branch )
41+
{
42+
// Make sure the branch isn't empty.
43+
List<T> fullBranch = branch.ToList();
44+
if ( fullBranch.Count == 0 )
45+
{
46+
return null;
47+
}
48+
49+
// Find matching leaf.
50+
T first = fullBranch.First();
51+
Tree<T> matchingLeaf = _children.FirstOrDefault( c => c.Value.Equals( first ) );
52+
if ( matchingLeaf == null )
53+
{
54+
// Leaf doens't exist yet, create full remaining branch.
55+
Tree<T> firstNew = null;
56+
Tree<T> current = this;
57+
foreach ( var leaf in fullBranch )
58+
{
59+
current = current.AddLeaf( leaf );
60+
if ( firstNew == null )
61+
{
62+
firstNew = current;
63+
}
64+
}
65+
return firstNew;
66+
}
67+
68+
// Leafs match, go down the branch.
69+
return matchingLeaf.AddBranch( fullBranch.Skip( 1 ) );
70+
}
71+
72+
/// <summary>
73+
/// Adds a new leaf to this tree.
74+
/// </summary>
75+
/// <param name = "leaf">The value to add as a leaf to this tree.</param>
76+
/// <returns>The newly added leaf.</returns>
77+
public Tree<T> AddLeaf( T leaf )
78+
{
79+
Tree<T> newLeaf = new Tree<T>( leaf ) { Parent = this };
80+
_children.Add( newLeaf );
81+
return newLeaf;
82+
}
83+
84+
/// <summary>
85+
/// Traverses nodes up until the tree until a passed evaluation returns true. Null is returned when reaching the top of the tree.
86+
/// </summary>
87+
/// <param name = "stopTraversal">Function which evaluates whether to stop at a given node or not.</param>
88+
/// <returns>The first node encountered where <see cref="stopTraversal" /> returns true. Null in case the top of the tree is reached.</returns>
89+
public Tree<T> TraverseUpUntil( Func<Tree<T>, bool> stopTraversal )
90+
{
91+
Tree<T> higherPeer = Parent;
92+
while ( higherPeer != null )
93+
{
94+
if ( stopTraversal( higherPeer ) )
95+
{
96+
break;
97+
}
98+
higherPeer = higherPeer.Parent;
99+
}
100+
101+
return higherPeer;
102+
}
103+
104+
/// <summary>
105+
/// Removes the current node from the parent tree.
106+
/// </summary>
107+
public void Remove()
108+
{
109+
Parent._children.Remove( this );
110+
}
111+
}
112+
}

0 commit comments

Comments
 (0)