/src/LinFu.Finders/FinderExtensions.cs

http://github.com/philiplaureano/LinFu · C# · 152 lines · 66 code · 13 blank · 73 comment · 3 complexity · 162e04f3ceb4731e20a7973c0eefc156 MD5 · raw file

  1. using System;
  2. using System.Collections.Generic;
  3. using LinFu.Finders.Interfaces;
  4. namespace LinFu.Finders
  5. {
  6. /// <summary>
  7. /// A class that adds fuzzy search support to <see cref="IList{T}" /> instances.
  8. /// </summary>
  9. public static class FinderExtensions
  10. {
  11. /// <summary>
  12. /// Applies a criteria to the <paramref name="list" /> of
  13. /// fuzzy items.
  14. /// </summary>
  15. /// <typeparam name="TItem">The type of item to test.</typeparam>
  16. /// <param name="list">
  17. /// The list of <see cref="IFuzzyItem{T}" /> instances that represent a single test case in a fuzzy
  18. /// search.
  19. /// </param>
  20. /// <param name="criteria">The criteria to test against each item in the list.</param>
  21. public static void AddCriteria<TItem>(this IList<IFuzzyItem<TItem>> list, ICriteria<TItem> criteria)
  22. {
  23. foreach (var item in list)
  24. {
  25. if (item == null)
  26. continue;
  27. item.Test(criteria);
  28. }
  29. }
  30. /// <summary>
  31. /// Applies a criteria to the <paramref name="list" /> of
  32. /// fuzzy items using the given <paramref name="predicate" />.
  33. /// </summary>
  34. /// <typeparam name="TItem">The type of item to test.</typeparam>
  35. /// <param name="list">
  36. /// The list of <see cref="IFuzzyItem{T}" /> instances that represent a single test case in a fuzzy
  37. /// search.
  38. /// </param>
  39. /// <param name="predicate">The condition that will be used to test the target item.</param>
  40. public static void AddCriteria<TItem>(this IList<IFuzzyItem<TItem>> list, Func<TItem, bool> predicate)
  41. {
  42. list.AddCriteria(predicate, CriteriaType.Standard);
  43. }
  44. /// <summary>
  45. /// Applies a criteria to the <paramref name="list" /> of
  46. /// fuzzy items using the given <paramref name="predicate" />.
  47. /// </summary>
  48. /// <typeparam name="TItem">The type of item to test.</typeparam>
  49. /// <param name="list">
  50. /// The list of <see cref="IFuzzyItem{T}" /> instances that represent a single test case in a fuzzy
  51. /// search.
  52. /// </param>
  53. /// <param name="predicate">The condition that will be used to test the target item.</param>
  54. /// <param name="criteriaType">The <see cref="CriteriaType" /> to associate with the predicate.</param>
  55. public static void AddCriteria<TItem>(this IList<IFuzzyItem<TItem>> list, Func<TItem, bool> predicate,
  56. CriteriaType criteriaType)
  57. {
  58. const int defaultWeight = 1;
  59. list.AddCriteria(predicate, criteriaType, defaultWeight);
  60. }
  61. /// <summary>
  62. /// Applies a criteria to the <paramref name="list" /> of
  63. /// fuzzy items using the given <paramref name="predicate" />.
  64. /// </summary>
  65. /// <typeparam name="TItem">The type of item to test.</typeparam>
  66. /// <param name="list">
  67. /// The list of <see cref="IFuzzyItem{T}" /> instances that represent a single test case in a fuzzy
  68. /// search.
  69. /// </param>
  70. /// <param name="predicate">The condition that will be used to test the target item.</param>
  71. /// <param name="criteriaType">The <see cref="CriteriaType" /> to associate with the predicate.</param>
  72. /// <param name="weight">
  73. /// The weight of the predicate value expressed in the number of tests that will be counted
  74. /// for/against the target item as a result of the predicate.
  75. /// </param>
  76. public static void AddCriteria<TItem>(this IList<IFuzzyItem<TItem>> list, Func<TItem, bool> predicate,
  77. CriteriaType criteriaType, int weight)
  78. {
  79. var criteria = new Criteria<TItem>
  80. {
  81. Predicate = predicate,
  82. Weight = weight,
  83. Type = criteriaType
  84. };
  85. list.AddCriteria(criteria);
  86. }
  87. /// <summary>
  88. /// Adds an item to a fuzzy list.
  89. /// </summary>
  90. /// <typeparam name="T">The type of the item being added.</typeparam>
  91. /// <param name="list">The fuzzy list that will contain the new item.</param>
  92. /// <param name="item">The item being added.</param>
  93. public static void Add<T>(this IList<IFuzzyItem<T>> list, T item)
  94. {
  95. list.Add(new FuzzyItem<T>(item));
  96. }
  97. /// <summary>
  98. /// Returns the FuzzyItem with the highest confidence score in a given
  99. /// <see cref="IFuzzyItem{T}" /> list.
  100. /// </summary>
  101. /// <typeparam name="TItem">The type of item being compared.</typeparam>
  102. /// <param name="list">The fuzzy list that contains the list of possible matches.</param>
  103. /// <returns>The item with the highest match.</returns>
  104. public static IFuzzyItem<TItem> BestMatch<TItem>(this IList<IFuzzyItem<TItem>> list)
  105. {
  106. double bestScore = 0;
  107. IFuzzyItem<TItem> bestMatch = null;
  108. foreach (var item in list)
  109. {
  110. if (item.Confidence <= bestScore)
  111. continue;
  112. bestMatch = item;
  113. bestScore = item.Confidence;
  114. }
  115. return bestMatch;
  116. }
  117. /// <summary>
  118. /// Resets the scores of all fuzzy items in the current list.
  119. /// </summary>
  120. /// <typeparam name="TItem">The target item type.</typeparam>
  121. /// <param name="list">The fuzzy list itself.</param>
  122. public static void Reset<TItem>(this IList<IFuzzyItem<TItem>> list)
  123. {
  124. foreach (var item in list) item.Reset();
  125. }
  126. /// <summary>
  127. /// Converts a list into a list of <see cref="IFuzzyItem{T}" /> objects.
  128. /// </summary>
  129. /// <typeparam name="TItem">The item type will be used in the fuzzy search.</typeparam>
  130. /// <param name="items">The target list to be converted.</param>
  131. /// <returns>A fuzzy list containing the elements from the given list.</returns>
  132. public static IList<IFuzzyItem<TItem>> AsFuzzyList<TItem>(this IEnumerable<TItem> items)
  133. {
  134. var result = new List<IFuzzyItem<TItem>>();
  135. foreach (var item in items) result.Add(item);
  136. return result;
  137. }
  138. }
  139. }