2012-12-19 20 views
5

Próbuję filtrować listę ciągów na podstawie liczby słów w każdym ciągu. Zakładam, że przycinałeś dowolną białą przestrzeń na końcach łańcucha, a następnie policzyłeś liczbę spacji w ciągu, tak aby WordCount = NumberOfSpaces + 1. Czy to jest najbardziej efektywny sposób na zrobienie tego? Wiem, że do filtrowania na podstawie liczby znaków następujące działa dobrze ... po prostu nie mogę dowiedzieć się, jak napisać to zwięźle za pomocą C#/LINQ.Filtrowanie ciągu znaków na podstawie liczby słów

if (checkBox_MinMaxChars.Checked) 
{ 
    int minChar = int.Parse(numeric_MinChars.Text); 
    int maxChar = int.Parse(numeric_MaxChars.Text); 

    myList = myList.Where(x => 
           x.Length >= minChar && 
           x.Length <= maxChar).ToList(); 
} 

Jakieś pomysły na liczenie słów?

UPDATE: To działało jak urok ... Dzięki Mathew:

int minWords = int.Parse(numeric_MinWords.Text); 
int maxWords = int.Parse(numeric_MaxWords.Text); 

sortBox1 = sortBox1.Where(x => x.Trim().Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries).Count() >= minWords && 
           x.Trim().Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries).Count() <= maxWords).ToList(); 

Odpowiedz

8

Chciałbym podejść do tego w sposób bardziej uproszczony sposób, ponieważ wyrazili, że przestrzeń może być stosowany jako ogranicznik niezawodnie tak:

var str = "  the string to split and count  "; 
var wordCount = str.Trim().Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries).Count(); 

EDIT:

Jeśli optymalna perforamnce jest konieczne i zużycie pamięci jest problemem można nakaz e własną metodę i dźwigni IndexOf() (choć istnieje wiele możliwości do realizacji na problem jak to, ja po prostu wolę ponownego wykorzystania, a nie od-nowa konstrukcja code):

public int WordCount(string s) { 
     const int DONE = -1; 
     var wordCount = 0; 
     var index = 0; 
     var str = s.Trim(); 
     while (index != DONE) { 
      wordCount++; 
      index = str.IndexOf(" ", index + 1); 
     } 
     return wordCount; 
    } 
+0

Dzięki Mathew ... Poniższe działało jak urok! – Jeagr

+0

int minWords = int.Parse (numeric_MinWords.Text); int maxWords = int.Parse (numeric_MaxWords.Text); sortBox1 = sortBox1.Where (x => x.Trim(). Split (nowy char [] {''}, StringSplitOptions.RemoveEmptyEntries) .Count()> = minWords && x.Trim(). Split (nowy char [] {''}, StringSplitOptions.RemoveEmptyEntries) .Count() <= maxWords) .ToList(); – Jeagr

+0

Czy ta metoda jest bardziej wydajna niż korzystanie z zapytań LINQ? – Jeagr

1

jak o dzielenie ciąg do tablicy za pomocą przestrzeń i to liczenie?

s.Split().Count() 

usunięta przestrzeń :)

+0

dodanie RemoveEmptyEntries jak w odpowiedzi Mateusza byłoby idd byłoby lepsze :) – ufosnowcat

+1

Nie trzeba używać "" " ', wystarczy użyć' string.Split() 'bez argumentów (lub null), a' Split' przyjmuje znaki spacji jako separator. –

3

można podejść do liczenia słów jest w porządku. String.Split da podobny wynik przy większym wykorzystaniu pamięci.

niż tylko realizować swoją funkcję int WordCount(string text) i przekazać go do Gdzie:

myList.Where(s => WordCount(s) > minWordCount) 
1

Chcesz wszystkie struny słowo liczy się w podanym zakresie?

int minCount = 10; 
int maxCount = 15; 
IEnumerable<string> result = list 
    .Select(String => new { String, Words = String.Split() }) 
    .Where(x => x.Words.Length >= minCount 
      && x.Words.Length <= maxCount) 
    .Select(x => x.String);