我是WPF的新手,所以这可能是一个简单的问题。我有一个应用程序,它从csv文件中读取一些单词并将它们存储在字符串列表中。我想要做的是参数化这个列表,以显示我的列表中最流行的单词。所以在我的UI中我想要一个文本框,当我输入一个例如5将过滤原始列表,仅在新列表中留下5个最受欢迎(频繁)的单词。任何人都可以协助这最后一步吗?谢谢 -
public class VM
{
public VM()
{
Words = LoadWords(fileList);
}
public IEnumerable<string> Words { get; private set; }
string[] fileList = Directory.GetFiles(@"Z:\My Documents\", "*.csv");
private static IEnumerable<string> LoadWords(String[] fileList)
{
List<String> words = new List<String>();
//
if (fileList.Length == 1)
{
try
{
foreach (String line in File.ReadAllLines(fileList[0]))
{
string[] rows = line.Split(',');
words.AddRange(rows);
}
}
catch (Exception ex)
{
System.Windows.MessageBox.Show(ex.Message, "Problem!");
}
}
else
{
System.Windows.MessageBox.Show("Please ensure that you have ONE read file in the source folder.", "Problem!");
}
return words;
}
}
答案 0 :(得分: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 :(得分:1)
您可以使用CollectionViewSource.GetDefaultView(viewModel.Words)
,它会返回ICollectionView
。
ICollectionView
公开Filter
类型的Predicate<object>
属性,您可以参与过滤。
所以常见的情况如下:
您可以找到过滤器属性使用here的工作示例。如果您遇到代码,请告诉我。
答案 2 :(得分: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);
}
通过在linq select子句中使用排序可以缩短Thsi,但我也希望向您介绍内联lambdas和可扩展的扩展。
简短版可以是:
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();
答案 3 :(得分: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);
}
}