Repository navigation
Expand file tree
/
Copy pathFinderExtensions.cs
More file actions
174 lines (159 loc) · 8.08 KB
/
Copy pathFinderExtensions.cs
File metadata and controls
174 lines (159 loc) · 8.08 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using LinFu.Finders.Interfaces;
namespace LinFu.Finders
{
/// <summary>
/// A class that adds fuzzy search support to <see cref="IList{T}"/> instances.
/// </summary>
public static class FinderExtensions
{
/// <summary>
/// Applies a criteria to the <paramref name="list"/> of
/// fuzzy items.
/// </summary>
/// <typeparam name="TItem">The type of item to test.</typeparam>
/// <param name="list">The list of <see cref="IFuzzyItem{T}"/> instances that represent a single test case in a fuzzy search.</param>
/// <param name="criteria">The criteria to test against each item in the list.</param>
public static void AddCriteria<TItem>(this IEnumerable<IFuzzyItem<TItem>> list, ICriteria<TItem> criteria)
{
foreach (var item in list)
{
if (item == null)
continue;
item.Test(criteria);
}
}
/// <summary>
/// Applies a criteria to the <paramref name="list"/> of
/// fuzzy items using the given <paramref name="predicate"/>.
/// </summary>
/// <typeparam name="TItem">The type of item to test.</typeparam>
/// <param name="list">The list of <see cref="IFuzzyItem{T}"/> instances that represent a single test case in a fuzzy search.</param>
/// <param name="predicate">The condition that will be used to test the target item.</param>
public static void AddCriteria<TItem>(this IEnumerable<IFuzzyItem<TItem>> list, Func<TItem, bool> predicate)
{
list.AddCriteria(predicate, CriteriaType.Standard);
}
/// <summary>
/// Applies a criteria to the <paramref name="list"/> of
/// fuzzy items using the given <paramref name="predicate"/>.
/// </summary>
/// <typeparam name="TItem">The type of item to test.</typeparam>
/// <param name="list">The list of <see cref="IFuzzyItem{T}"/> instances that represent a single test case in a fuzzy search.</param>
/// <param name="predicate">The condition that will be used to test the target item.</param>
/// <param name="criteriaType">The <see cref="CriteriaType"/> to associate with the predicate.</param>
public static void AddCriteria<TItem>(this IEnumerable<IFuzzyItem<TItem>> list, Func<TItem, bool> predicate,
CriteriaType criteriaType)
{
const int defaultWeight = 1;
list.AddCriteria(predicate, criteriaType, defaultWeight);
}
/// <summary>
/// Applies a criteria to the <paramref name="list"/> of
/// fuzzy items using the given <paramref name="predicate"/>.
/// </summary>
/// <typeparam name="TItem">The type of item to test.</typeparam>
/// <param name="list">The list of <see cref="IFuzzyItem{T}"/> instances that represent a single test case in a fuzzy search.</param>
/// <param name="predicate">The condition that will be used to test the target item.</param>
/// <param name="criteriaType">The <see cref="CriteriaType"/> to associate with the predicate.</param>
/// <param name="weight">The weight of the predicate value expressed in the number of tests that will be counted for/against the target item as a result of the predicate.</param>
public static void AddCriteria<TItem>(this IEnumerable<IFuzzyItem<TItem>> list, Func<TItem, bool> predicate, CriteriaType criteriaType, int weight)
{
var criteria = new Criteria<TItem>()
{
Predicate = predicate,
Weight = weight,
Type = criteriaType
};
list.AddCriteria(criteria);
}
/// <summary>
/// Adds an item to a fuzzy list.
/// </summary>
/// <typeparam name="T">The type of the item being added.</typeparam>
/// <param name="list">The fuzzy list that will contain the new item.</param>
/// <param name="item">The item being added.</param>
public static void Add<T>(this IList<IFuzzyItem<T>> list, T item)
{
list.Add(new FuzzyItem<T>(item));
}
/// <summary>
/// Returns the FuzzyItem with the highest confidence score in a given
/// <see cref="IFuzzyItem{T}"/> list.
/// </summary>
/// <typeparam name="TItem">The type of item being compared.</typeparam>
/// <param name="list">The fuzzy list that contains the list of possible matches.</param>
/// <param name="tolerance">The tolerance level that determines the minimum percentage for a valid match (ranges between 0.0 and 1.0)</param>
/// <returns>The item with the highest match.</returns>
public static IFuzzyItem<TItem> BestMatch<TItem>(this IEnumerable<IFuzzyItem<TItem>> list, double tolerance)
{
if (tolerance < 0 || tolerance > 1)
throw new ArgumentOutOfRangeException("tolerance");
double bestScore = 0;
IFuzzyItem<TItem> bestMatch = null;
foreach (var item in list)
{
if (item.Confidence <= bestScore || item.Confidence < tolerance)
continue;
bestMatch = item;
bestScore = item.Confidence;
}
return bestMatch;
}
/// <summary>
/// Returns the FuzzyItems with the minimum tolerance score in a given
/// <see cref="IFuzzyItem{T}"/> list.
/// </summary>
/// <typeparam name="TItem">The type of item being compared.</typeparam>
/// <param name="list">The fuzzy list that contains the list of possible matches.</param>
/// <param name="tolerance">The tolerance level that determines the minimum percentage for a valid match (ranges between 0.0 and 1.0)</param>
/// <returns>The items that match the tolerance threshold</returns>
public static IEnumerable<IFuzzyItem<TItem>> BestMatches<TItem>(this IEnumerable<IFuzzyItem<TItem>> list, double tolerance = 1)
{
if (tolerance < 0 || tolerance > 1)
throw new ArgumentOutOfRangeException("tolerance");
return list.Where(item => item.Confidence >= tolerance);
}
/// <summary>
/// Returns the FuzzyItem with the highest confidence score in a given
/// <see cref="IFuzzyItem{T}"/> list.
/// </summary>
/// <typeparam name="TItem">The type of item being compared.</typeparam>
/// <param name="list">The fuzzy list that contains the list of possible matches.</param>
/// <returns>The item with the highest match.</returns>
public static IFuzzyItem<TItem> BestMatch<TItem>(this IEnumerable<IFuzzyItem<TItem>> list)
{
return BestMatch(list, .51);
}
/// <summary>
/// Resets the scores of all fuzzy items in the current list.
/// </summary>
/// <typeparam name="TItem">The target item type.</typeparam>
/// <param name="list">The fuzzy list itself.</param>
public static void Reset<TItem>(this IEnumerable<IFuzzyItem<TItem>> list)
{
foreach(var item in list)
{
item.Reset();
}
}
/// <summary>
/// Converts a list into a list of <see cref="IFuzzyItem{T}"/> objects.
/// </summary>
/// <typeparam name="TItem">The item type will be used in the fuzzy search.</typeparam>
/// <param name="items">The target list to be converted.</param>
/// <returns>A fuzzy list containing the elements from the given list.</returns>
public static IList<IFuzzyItem<TItem>> AsFuzzyList<TItem>(this IEnumerable<TItem> items)
{
var result = new List<IFuzzyItem<TItem>>();
foreach(var item in items)
{
result.Add(item);
}
return result;
}
}
}