2012-03-29 14 views
6

Así que tengo una lista con Materiel-objects. En Materiel tengo 15 métodos get y set. Quiero construir un método de búsqueda que bucles todos los objetos en la lista, y todas las variables en cada objeto Materiel. La parte de bucle es bastante fácil, pero estoy luchando con la cuerda-contiene-parte. El término de búsqueda podría ser, por ejemplo, "acto", y debería obtener un hit para "Tractor". He intentado utilizar la clase cadena-Contiene, pero hasta donde sé, solo verifica que la secuencia comience en la posición 0. Entonces "Tra" recibe un golpe, pero no "acto".C# contiene parte de la cadena

¿Hay alguna generación en las clases, o debería programar yo mismo?

Disculpe por la mala explicación.

Mi código. Ahora veo que me da golpes de la subcadena, sino también otros resultados :)

protected void Button_search_Click(object sender, EventArgs e) 
    { 
     string searchTerm = TextBox1.Text.ToString().ToLower(); 

     TableRow row; 
     TableCell cell; 

     int rowNumber = 1; 

     foreach (Materiell mat in allItems) 
     { 
      if (searchTerm.Contains(mat.itemID.ToString().ToLower()) || 
       searchTerm.Contains(mat.manufacturer.ToLower()) || 
       searchTerm.Contains(mat.model.ToLower()) || 
       searchTerm.Contains(mat.serialNo.ToLower()) || 
       searchTerm.Contains(mat.dateProd.ToString().ToLower()) || 
       searchTerm.Contains(mat.location.ToLower()) || 
       searchTerm.Contains(mat.mainCategory.ToLower()) || 
       searchTerm.Contains(mat.subCategory.ToLower()) || 
       searchTerm.Contains(mat.dateAcquired.ToString().ToLower()) || 
       searchTerm.Contains(mat.price.ToString().ToLower()) || 
       searchTerm.Contains(mat.ownerID.ToString().ToLower()) || 
       searchTerm.Contains(mat.extra.ToString().ToLower()) || 
       searchTerm.Contains(mat.textComment.ToLower()) || 
       searchTerm.Contains(mat.active.ToString().ToLower())) 
      { 
       row = new TableRow(); 
       row.ID = "row" + rowNumber.ToString(); 
       rowNumber++; 

       cell = new TableCell(); 
       cell.Text = "<a href=\"#\" class=\"opendiv\">" + mat.itemID.ToString() + "</a>"; 
       row.Cells.Add(cell); 

       cell = new TableCell(); 
       cell.Text = mat.manufacturer.ToString(); 
       row.Cells.Add(cell); 

       cell = new TableCell(); 
       cell.Text = mat.model.ToString(); 
       row.Cells.Add(cell); 

       cell = new TableCell(); 
       cell.Text = mat.serialNo.ToString(); 
       row.Cells.Add(cell); 

       cell = new TableCell(); 
       cell.Text = mat.dateProd.ToString(); 
       row.Cells.Add(cell); 

       cell = new TableCell(); 
       cell.Text = mat.location.ToString(); 
       row.Cells.Add(cell); 

       cell = new TableCell(); 
       cell.Text = mat.mainCategory.ToString(); 
       row.Cells.Add(cell); 

       cell = new TableCell(); 
       cell.Text = mat.subCategory.ToString(); 
       row.Cells.Add(cell); 

       cell = new TableCell(); 
       cell.Text = mat.dateAcquired.ToString(); 
       row.Cells.Add(cell); 

       cell = new TableCell(); 
       cell.Text = mat.price.ToString(); 
       row.Cells.Add(cell); 

       cell = new TableCell(); 
       cell.Text = mat.ownerID.ToString(); 
       row.Cells.Add(cell); 

       cell = new TableCell(); 
       cell.Text = mat.extra.ToString(); 
       row.Cells.Add(cell); 

       cell = new TableCell(); 
       cell.Text = mat.ownDefData.ToString(); 
       row.Cells.Add(cell); 

       cell = new TableCell(); 
       cell.Text = mat.textComment.ToString(); 
       row.Cells.Add(cell); 

       cell = new TableCell(); 
       cell.Text = mat.active.ToString(); 
       row.Cells.Add(cell); 

       Table1.Rows.Add(row); 
      } 
     } 
    } 
+2

Podría publicar un fragmento de código, porque de acuerdo a la documentación "acto" debería llegar en "Tractor": http://msdn.microsoft.com/en-us/library/dy85x1sa(v=vs.100).aspx – LexyStardust

+2

'" Tractor ".Contains (" acto ")' debe devolver 'true'. Es posible que desee publicar algo de su código para que podamos ver lo que ha intentado hasta ahora y dónde puede estar yendo mal. – Rawling

+0

Gah. Ninguna de las respuestas aborda el punto. Mira Lucene.NET, tal vez (parece que estás buscando la búsqueda/indexación de texto completo; ¿es quizás una aplicación de tipo biblioteca?) – sehe

Respuesta

11

"some string".Contains("str") devolverá cierto, ¿está teniendo problemas con la sensibilidad a las mayúsculas y minúsculas?

Si lo que podría utilizar esto:

public static bool Contains(this string source, string toCheck, StringComparison comp) { 
    return source.IndexOf(toCheck, comp) >= 0; 
} 

string title = "STRING"; 
bool contains = title.Contains("string", StringComparison.OrdinalIgnoreCase); 

(Tomado de Case insensitive 'Contains(string)')

+1

Buen método de extensión. ¡Considera eso robado! – LexyStardust

+0

Derecha ... El método 'IndexOf' tiene un método' StringComparison' que el método 'Contains' no tiene, no se pensó en eso. Eso es mejor que usar 'ToUpper' antes de verificar. Incorporado al instante en el proyecto en el que estoy trabajando actualmente. :) – Guffa

+0

OMG. Sorprendentemente, esto fue aceptado como la respuesta. Bueno, en caso de que quiera una búsqueda de texto completo, consulte aquí: http://stackoverflow.com/questions/9923158/c-sharp-contains-part-of-string/9924084#9924084 – sehe

3

Uso IndexOf

string searchWithinThis = "ABCDEFGHIJKLMNOP"; 
string searchForThis = "DEF"; 
int firstCharacter = searchWithinThis.IndexOf(searchForThis); 

Console.WriteLine("First occurrence: {0}", firstCharacter); 

si no se encuentra la subcadena, devuelve -1. Es muy útil también para saber dónde se encuentra la cadena.

+0

En realidad, ya lo hace. El método 'String.Contains' simplemente llama a' IndexOf'. – Guffa

0

El método string.Contains tiene un aspecto de la subcadena en cualquier lugar de la cadena.

"asdf".Contains("as") --> True 
"asdf".Contains("sd") --> True 
"asdf".Contains("df") --> True 
"asdf".Contains("xy") --> False 

Sin embargo, la comparación entre mayúsculas y sensetive, lo que puede necesitar para convertir caso si desea hacer una caja de búsqueda insesetive:

"Asdf".Contains("as") --> False 
"Asdf".Contains("As") --> True 

"Asdf".ToUpper().Contains("as".ToUpper()) --> True 
1
class SearchInString 
{ 
    static void Main() 
    { 
     string strn= "A great things are happen with great humans."; 
     System.Console.WriteLine("'{0}'",strn); 

     bool case1= strn.StartsWith("A great"); 
     System.Console.WriteLine("starts with 'A great'? {0}", case1); 

     bool case2= strn.StartsWith("A great", System.StringComparison.OrdinalIgnoreCase); 
     System.Console.WriteLine("starts with 'A great'? {0} (ignoring case)", case2); 

     bool case3= strn.EndsWith("."); 
     System.Console.WriteLine("ends with '.'? {0}", case3); 

     int start= strn.IndexOf("great"); 
     int end= strn.LastIndexOf("great"); 
     string strn2 = strn.Substring(start, end- start); 
     System.Console.WriteLine("between two 'great' words: '{0}'", strn2); 
    } 
} 
2

Para mierdas y risitas me pareció que era una buen proyecto para la hora del almuerzo para encontrar una solución simple, pero 'elegante' para la Pregunta (como yo lo entendí :)):

Por ej.

// I made up a Material class for testing: 
public class Materiel 
{ 
    public string A { get; set; } 
    public int B { get; set; } 
    public DateTime? C { get; set; } 
    public string D { get; set; } 
    public Nested E { get; set; } 
}  

// [...] usage: 

foreach (var pattern in new[]{ "World" , "dick", "Dick", "ick", "2012", "Attach" }) 
    Console.WriteLine("{0} records match '{1}'", Database.Search(pattern).Count(), pattern); 

Salidas:

2 records match 'World' 
1 records match 'dick' 
1 records match 'Dick' 
2 records match 'ick' 
1 records match '2012' 
2 records match 'Attach' 

El código también soporta

  • regex partidos
  • cualquier tipo de propiedad (por ejemplo,DateTime anulables o clases anidadas)
  • que muestran cuales propiedad coincidía con el patrón/subcadena

disfrutar de:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Reflection; 
using System.Text.RegularExpressions; 

namespace AClient 
{ 
    public class Materiel 
    { 
     public string A { get; set; } 
     public int B { get; set; } 
     public DateTime? C { get; set; } 
     public string D { get; set; } 
     public Nested E { get; set; } 
    } 

    public struct Nested 
    { 
     public string Data { get; set; } 
     public override string ToString() { return string.Format("Extra: {0}", Data); } 
    } 


    public static class FullText 
    { 
     public class PropMatched<T> { public PropertyInfo Property; public T Item; } 

     public static IEnumerable<PropMatched<T> > ByProperty<T>(this IEnumerable<T> items, string substr) 
     { 
      return items.ByProperty(new Regex(Regex.Escape(substr), RegexOptions.IgnoreCase)); 
     } 

     public static IEnumerable<PropMatched<T> > ByProperty<T>(this IEnumerable<T> items, Regex pattern) 
     { 
      return items.Select(i => i.MatchingProperties(pattern)).Where(m => null != m); 
     } 

     public static IEnumerable<T> Search<T>(this IEnumerable<T> items, string substr) 
     { 
      return items.Search(new Regex(Regex.Escape(substr), RegexOptions.IgnoreCase)); 
     } 

     public static IEnumerable<T> Search<T>(this IEnumerable<T> items, Regex pattern) 
     { 
      return items.Where(i => null != i.MatchingProperties(pattern)); 
     } 

     public static PropMatched<T> MatchingProperties<T>(this T item, Regex pattern) 
     { 
      if (null == pattern || null == item) return null; 

      var properties = item.GetType().GetProperties(BindingFlags.Public | BindingFlags.FlattenHierarchy | BindingFlags.Instance); 
      var matches = from prop in properties 
          let val = prop.GetGetMethod(true).Invoke(item, new object[]{}) 
          where pattern.IsMatch((val??"").ToString()) 
          select prop; 

      var found = matches.FirstOrDefault(); 
      return found == null ? null : new PropMatched<T> {Item = item, Property = found}; 
     } 
    } 

    class Client 
    { 
     private static readonly IEnumerable<Materiel> Database = new List<Materiel> 
      { 
       new Materiel { 
         A = "Hello", B = 1, C = null, D = "World", 
         E = new Nested {Data = "Attachment"} 
        }, 
       new Materiel { 
         A = "Transfigured", B = 2, C = null, D = "Nights", 
         E = new Nested {Data = "Schoenberg"} 
        }, 
       new Materiel { 
         A = "Moby", B = 3, C = null, D = "Dick", 
         E = new Nested {Data = "Biographic"} 
        }, 
       new Materiel { 
         A = "Prick", B = 4, C = DateTime.Today, D = "World", 
         E = new Nested {Data = "Attachment"} 
        }, 
       new Materiel { 
         A = "Oh Noes", B = 2, C = null, D = "Nights", 
         E = new Nested {Data = "Schoenberg"} 
        }, 
      }; 


     static void Main() 
     { 
      foreach (var pattern in new[]{ "World" , "dick", "Dick", "ick", "2012", "Attach" }) 
       Console.WriteLine("{0} records match '{1}'", Database.Search(pattern).Count(), pattern); 

      // regex sample: 
      var regex = new Regex(@"N\w+s", RegexOptions.IgnoreCase); 

      Console.WriteLine(@"{0} records match regular expression 'N\w+s'", Database.Search(regex).Count()); 

      // with context info: 
      foreach (var contextMatch in Database.ByProperty(regex)) 
      { 
       Console.WriteLine("1 match of regex in propery {0} with value '{1}'", 
        contextMatch.Property.Name, contextMatch.Property.GetGetMethod().Invoke(contextMatch.Item, new object[0])); 

      } 
     } 
    } 
} 
+0

Véalo en vivo aquí: ** [ http://ideone.com/UWgQe](http://ideone.com/UWgQe)** – sehe

Cuestiones relacionadas