2011-05-05 5 views
2

저는 이것이 WPF를 처음 사용하기 때문에 이것은 아마도 쉬운 질문 일 것입니다. csv 파일에서 일부 단어를 읽고 문자열 목록에 저장하는 앱이 있습니다. 내가하려는 일은이 목록을 매개 변수화하여 목록에 가장 인기있는 단어를 표시하는 것입니다. 그래서 내 UI에서 나는 숫자를 입력 할 때 텍스트 상자를 원한다. 5는 원래 목록을 필터링하여 새 목록에 가장 자주 사용되는 5 개의 단어 만 남깁니다. 누구나이 마지막 단계를 도울 수 있습니까? 감사 -WPF 목록 필터링

답변

1

해당 단어의 수를 내림차순으로 정렬하여 단어별로 그룹화하는 LINQ 쿼리. 이

private static IEnumerable<string> GetTopWords(int Count) 
{ 
    var popularWords = (from w in words     
      group w by w 
      into grp 
      orderby grp.Count() descending 
      select grp.Key).Take(Count).ToList(); 
    return popularWords; 
} 
1

당신은 ICollectionView을 반환 CollectionViewSource.GetDefaultView(viewModel.Words)을 사용할 수보십시오.

ICollectionViewPredicate<object>Filter 속성을 필터링 할 수 있습니다.

  1. 뷰 모델은 속성 PopularCount를 노출하는이보기에 일부 텍스트 상자에 바인더 제본되어 : 같은

    그래서 일반적인 시나리오는 보인다.

  2. ViewModel은 PopularCount 속성이 변경되는 것을 수신 대기합니다.
  3. 알림이 발생하면 model은 viewModel.Words 컬렉션에 대한 ICollectionView를 가져 와서 Filter 속성을 설정합니다.

필터 속성 사용 예제 here을 찾을 수 있습니다. 코드가 붙어 있다면 알려주세요.

0

은 내가 '단어'목록의 그룹화 및 주문 당신이 원하는 경우에 확실하지 않다하지만 네이 그 일을하는 방법이 될 수있는 경우 :

int topN = 3; 
    List<string> topNWords = new List<string>(); 

    string[] words = new string[] { 
     "word5", 
     "word1", 
     "word1", 
     "word1", 
     "word2", 
     "word2", 
     "word2", 
     "word3", 
     "word3", 
     "word4", 
     "word5", 
     "word6", 
    }; 

    // [linq query][1] 
    var wordGroups = from s in words 
         group s by s into g 
         select new { Count = g.Count(), Word = g.Key }; 

    for (int i = 0; i < Math.Min(topN, wordGroups.Count()); i++) 
    { 
     // (g) => g.Count is a [lambda expression][2] 
     // .OrderBy and Reverse are IEnumerable extension methods 
     var element = wordGroups.OrderBy((g) => g.Count).Reverse().ElementAt(i); 
     topNWords.Add(element.Count + " - " + element.Word); 
    } 
Thsi를 사용하여 훨씬 짧은 만들어 질 수

linq select 절에서 주문했지만 인라인 lambdas과 ienumerable 확장을 소개하려고합니다.

짧은 버전 수 :

topNWords = (from s in words     
      group s by s 
      into g 
      orderby g.Count() descending 
      select g.Key).Take(Math.Min(topN, g.Count()).ToList(); 
0

대신 목록에있는 모든 단어를 읽고 다음 주파수에 따라 정렬의, 깨끗한 접근이 단어를 저장하는 사용자 정의 클래스 MyWord을 생성하는 것입니다 및 주파수. 파일을 읽는 동안 단어의 빈도를 증가시킬 수 있습니다. 클래스는 빈도에 따라 단어를 비교하기 위해 IComparable<T>을 구현할 수 있습니다.

public class MyWord : IComparable<MyWord> 
{ 
    public MyWord(string word) 
    { 
     this.Word = word; 
     this.Frequency = 0; 
    } 

    public MyWord(string word, int frequency) 
    { 
     this.Word = word; 
     this.Frequency = frequency; 
    } 

    public string Word { get; private set;}   
    public int Frequency { get; private set;} 

    public void IncrementFrequency() 
    { 
     this.Frequency++; 
    } 

    public void DecrementFrequency() 
    { 
     this.Frequency--; 
    } 

    public int CompareTo(MyWord secondWord) 
    { 
     return this.Frequency.CompareTo(secondWord.Frequency); 
    } 
} 

메인 클래스 VM는 것이 회원

public IEnumerable<MyWord> Words { get; private set; } 

private void ShowMostPopularWords(int numberOfWords) 
{ 
    SortMyWordsDescending(); 
    listBox1.Items.Clear(); 

    for (int i = 0; i < numberOfWords; i++) 
    { 
     listBox1.Items.Add(this.Words.ElementAt(i).Word + "|" + this.Words.ElementAt(i).Frequency); 
    } 
} 

그리고 ShowMostPopularWords()

private void Button_Click(object sender, RoutedEventArgs e) 
{ 
    int numberOfWords; 
    if(Int32.TryParse(textBox1.Text, NumberStyles.Integer, CultureInfo.CurrentUICulture, out numberOfWords)) 
    { 
     ShowMostPopularWords(numberOfWords); 
    } 
} 
에 대한 호출