2012-03-29 19 views
6

Quindi ho una lista con oggetti Materiel. In Materiel ho 15 metodi get e set. Voglio costruire un metodo di ricerca che cerchi tutti gli oggetti nella lista e tutte le variabili in ogni oggetto Materiel. La parte di loop è abbastanza facile, ma sto lottando con la stringa-contiene-parte. Il termine di ricerca potrebbe ad esempio essere "acto", e dovrei ottenere un successo per "Tractor". Ho provato a utilizzare la classe string-Contains, ma per quanto posso capire controlla solo la stringa che inizia nella posizione 0. Quindi "Tra" ottiene un hit, ma non "acto".C# contiene parte della stringa

C'è qualche build in classi, o dovrei programmarne uno da solo?

Ci scusiamo per la cattiva spiegazione.

Il mio codice. Vedo ora che ottengo risultati per la stringa, ma anche altri risultati :)

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

Potrebbe inviare un frammento di codice perché secondo la documentazione "acto" dovrebbe colpire in "Trattore": http://msdn.microsoft.com/en-us/library/dy85x1sa(v=vs.100).aspx – LexyStardust

+2

'" Trattore ".Contains (" acto ")' dovrebbe restituire 'true'. Potresti postare parte del tuo codice in modo da poter vedere ciò che hai provato finora e dove potresti sbagliare. – Rawling

+0

Gah. Nessuna delle risposte risponde al punto. Guarda Lucene.NET, forse (sembra che tu stia cercando la ricerca/indicizzazione di testo completo, è forse un'applicazione di tipo libreria?) – sehe

risposta

11

"some string".Contains("str") restituirà true, stai riscontrando problemi con la sesibilità del caso?

Se è così si potrebbe usare questo:

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); 

(Tratto da Case insensitive 'Contains(string)')

+1

Neat piccolo metodo di estensione. Considera quello rubato! – LexyStardust

+0

Right ... Il metodo 'IndexOf' ha un metodo' StringComparison' che il metodo 'Contains' manca, non ci ha pensato. È meglio che usare 'ToUpper' prima di controllare. Incorporato istantaneamente nel progetto a cui sto lavorando attualmente. :) – Guffa

+0

OMG. Sorprendentemente, questo è stato accettato come risposta. Bene, nel caso in cui volessi una ricerca a tutto campo, vedi qui: http://stackoverflow.com/questions/9923158/c-sharp-contains-part-of-string/9924084#9924084 – sehe

3

Usa IndexOf

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

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

se stringa non viene trovata, restituisce -1. È molto utile anche per sapere dove si trova la stringa.

+0

In realtà lo fa già. Il metodo 'String.Contains' chiama solo' IndexOf'. – Guffa

0

Il metodo string.Contains ha un aspetto per la stringa in qualsiasi punto della stringa.

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

Il confronto è comunque tra maiuscole sensetive, quindi potrebbe essere necessario convertire caso, se si vuole fare un caso di ricerca 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

Per merde e risatine ho pensato che fosse un bel progetto di pausa pranzo per trovare una soluzione semplice, ma elegante alla domanda (come ho capito :)):

Es.

// 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); 

Uscite:

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

Il codice supporta anche

  • regex
  • eventuali tipi di proprietà (per esempioDateTimes nullable o classi nidificate)
  • mostrano che proprietà abbinato il modello/stringa

Enjoy:

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

Vedi qui dal vivo qui: ** [ http://ideone.com/UWgQe](http://ideone.com/UWgQe)** – sehe

Problemi correlati