fork download
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Reflection;
  5. using System.Text.RegularExpressions;
  6.  
  7. namespace AClient
  8. {
  9. public class Materiel
  10. {
  11. public string A { get; set; }
  12. public int B { get; set; }
  13. public DateTime? C { get; set; }
  14. public string D { get; set; }
  15. public Nested E { get; set; }
  16. }
  17.  
  18. public struct Nested
  19. {
  20. public string Data { get; set; }
  21. public override string ToString() { return string.Format("Extra: {0}", Data); }
  22. }
  23.  
  24.  
  25. public static class FullText
  26. {
  27. public class PropMatched<T> { public PropertyInfo Property; public T Item; }
  28.  
  29. public static IEnumerable<PropMatched<T> > ByProperty<T>(this IEnumerable<T> items, string substr)
  30. {
  31. return items.ByProperty(new Regex(Regex.Escape(substr), RegexOptions.IgnoreCase));
  32. }
  33.  
  34. public static IEnumerable<PropMatched<T> > ByProperty<T>(this IEnumerable<T> items, Regex pattern)
  35. {
  36. return items.Select(i => i.MatchingProperties(pattern)).Where(m => null != m);
  37. }
  38.  
  39. public static IEnumerable<T> Search<T>(this IEnumerable<T> items, string substr)
  40. {
  41. return items.Search(new Regex(Regex.Escape(substr), RegexOptions.IgnoreCase));
  42. }
  43.  
  44. public static IEnumerable<T> Search<T>(this IEnumerable<T> items, Regex pattern)
  45. {
  46. return items.Where(i => null != i.MatchingProperties(pattern));
  47. }
  48.  
  49. public static PropMatched<T> MatchingProperties<T>(this T item, Regex pattern)
  50. {
  51. if (null == pattern || null == item) return null;
  52.  
  53. var properties = item.GetType().GetProperties(BindingFlags.Public | BindingFlags.FlattenHierarchy | BindingFlags.Instance);
  54. var matches = from prop in properties
  55. let val = prop.GetGetMethod(true).Invoke(item, new object[]{})
  56. where pattern.IsMatch((val??"").ToString())
  57. select prop;
  58.  
  59. var found = matches.FirstOrDefault();
  60. return found == null ? null : new PropMatched<T> {Item = item, Property = found};
  61. }
  62. }
  63.  
  64. class Client
  65. {
  66. private static readonly IEnumerable<Materiel> Database = new List<Materiel>
  67. {
  68. new Materiel {
  69. A = "Hello", B = 1, C = null, D = "World",
  70. E = new Nested {Data = "Attachment"}
  71. },
  72. new Materiel {
  73. A = "Transfigured", B = 2, C = null, D = "Nights",
  74. E = new Nested {Data = "Schoenberg"}
  75. },
  76. new Materiel {
  77. A = "Moby", B = 3, C = null, D = "Dick",
  78. E = new Nested {Data = "Biographic"}
  79. },
  80. new Materiel {
  81. A = "Prick", B = 4, C = DateTime.Today, D = "World",
  82. E = new Nested {Data = "Attachment"}
  83. },
  84. new Materiel {
  85. A = "Oh Noes", B = 2, C = null, D = "Nights",
  86. E = new Nested {Data = "Schoenberg"}
  87. },
  88. };
  89.  
  90.  
  91. static void Main()
  92. {
  93. foreach (var pattern in new[]{ "World" , "dick", "Dick", "ick", "2012", "Attach" })
  94. Console.WriteLine("{0} records match '{1}'", Database.Search(pattern).Count(), pattern);
  95.  
  96. // regex sample:
  97. var regex = new Regex(@"N\w+s", RegexOptions.IgnoreCase);
  98.  
  99. Console.WriteLine(@"{0} records match regular expression 'N\w+s'", Database.Search(regex).Count());
  100.  
  101. // with context info:
  102. foreach (var contextMatch in Database.ByProperty(regex))
  103. {
  104. Console.WriteLine("1 match of regex in propery {0} with value '{1}'",
  105. contextMatch.Property.Name, contextMatch.Property.GetGetMethod().Invoke(contextMatch.Item, new object[0]));
  106.  
  107. }
  108. }
  109. }
  110. }
  111.  
  112.  
  113.  
Success #stdin #stdout 0.09s 37680KB
stdin
Standard input is empty
stdout
2 records match 'World'
1 records match 'dick'
1 records match 'Dick'
2 records match 'ick'
1 records match '2012'
2 records match 'Attach'
2 records match regular expression 'N\w+s'
1 match of regex in propery D with value 'Nights'
1 match of regex in propery A with value 'Oh Noes'