我有一个已从字典文件中读入的字符串列表(按字母顺序排序)。我想创建每个起始字母的最后一个位置的索引,所以如果有1000个以A开头的单词,它将被记录为位置999(因为数组从0开始)。以B开头的1000个单词意味着B的结束位置是1999年,依此类推。这些位置值将存储在一个int数组中。
我能想到的唯一方法是循环遍历整个列表,并且还有很多if语句来查看单词的第一个字母。不是最优雅的解决方案。
有没有人知道一种简单的方法,而不是26条if语句?
编辑:这样做的目的是生成随机单词。如果我想要一个以B开头的单词,我会在1000到1999之间生成一个随机数,然后从列表中的那个位置获取单词。
答案 0 :(得分:8)
好吧,您可以使用LINQ创建一个字典:
// Note: assumes no empty words
Dictionary<char, int> lastEntries = words
.Select((index, value) => new { index, value })
.GroupBy(pair => pair.value[0])
.ToDictionary(g => g.Key, g => g.Max(p => p.index));
或者更有用的是,保留第一个和最后一个索引:
Dictionary<char, Tuple<int, int>> entryMinMax = words
.Select((value, index) => new { value, index })
.GroupBy(pair => pair.value[0])
.ToDictionary(g => g.Key,
g => Tuple.Of(g.Min(p => p.index), g.Max(p => p.index));
或者,如果要点是用第一个字母有效地对单词进行分组,那么只需使用查找:
ILookup<char, string> lookup = words.ToLookup(word => word[0]);
然后你可以使用:
char first = 'B'; // Or whatever
Random rng = new Random(); // But don't create a new one each time...
var range = lookup[first];
var count = range.Count();
if (count == 0)
{
// No words starting with that letter!
}
int index = random.Next(count);
var randomWord = range.ElementAt(index);
答案 1 :(得分:3)
我会以不同的方式处理这个问题,并且它不需要订购它。
public List<string> GetAllStringsStartingWith(char startsWith, List<string> allWords)
{
List<string> letterSpecificWords = allWords.FindAll(word => word.ToLower()[0].Equals(startsWith));
return letterSpecificWords;
}
从这里开始,你现在有一个列表,其中只包含以字母&#34; a&#34;开头的单词。你可以改变&#34; a&#34;用一个变量来表示你需要的变量,并且它总会找到所有以该字母开头的变量。
注意:
word.ToLower()用于确保它是小写值。如果您切换要查找变量的字母,您也希望对变量执行此操作。
您仍然需要处理随机整数,但现在您可以使用准确的计数(words.Count)。
这假定列表中没有空条目。
words.ToLower()[0]获取第一个字符
答案 2 :(得分:0)
这可能是xy问题的一个例子。 为什么你需要每个字母最后一次出现的索引吗?很可能,这不是你想做的事。
无论如何要回答您的问题,对于每封信,您都可以使用FindLastIndex方法。
int index = myList.FindLastIndex(i => i.ToLower()[0] == 'a');
我更喜欢Jon Skeet的方法,因为你不必遍历每个字母。
答案 3 :(得分:0)
您可以使用for循环遍历列表,并将当前元素的第一个字母与下一个元素的第一个字母进行比较。如果字母相同则继续循环,如果不同则存储下一个元素的索引,然后继续循环。
答案 4 :(得分:0)
要检索最后一次:
words.LastOrDefault(i => i[0].ToLower() == 'a');
获取索引:
words.FindLastIndex(i => i[0].ToLower() == 'a');
答案 5 :(得分:0)
您可以按一个周期执行此操作:
public Dictionary<char, int> GetCharIndex(IList<string> words)
{
if (words == null || !words.Any()) throw new ArgumentException("words can't be null or empty");
Dictionary<char, int> charIndex = new Dictionary<char, int>();
char prevLetter = words[0][0];
for(int i = 1;i < words.Count;i++)
{
char letter = words[i][0];
if (letter != prevLetter) //change of first letter of the word -> add previous letter to dictionary
{
charIndex.Add(prevLetter, i - 1);
prevLetter = letter;
}
}
charIndex.Add(words[words.Count - 1][0], words.Count - 1); //special case for last word
return charIndex;
}