#c# #streamreader
#c# #streamreader
Вопрос:
Сейчас я использую streamreader для чтения файла с именами людей, это текстовый файл с именами людей, так что, очевидно, есть дубликаты, и я хочу иметь возможность отображать, у скольких людей сейчас такие же, например:
josh
alex
josh
john
alex
Я хочу, чтобы это говорило,
josh 2
alex 2
john 1
но, похоже, я не могу найти простой способ сделать это, какой был бы самый простой способ сделать это,
Ответ №1:
Я бы сказал, используйте Dictionary<string, int>
.
Dictionary<string, int> firstNames = new Dictionary<string, int>();
foreach (string name in YourListWithNames)
{
if (!firstNames.ContainsKey(name))
firstNames.Add(name, 1);
else
firstNames[name] = 1;
}
Конечно, есть много разных путей к решению, но я бы решил это именно так. Я еще не запускал этот код, но, я думаю, это поможет вам.
Ответ №2:
Попробуйте это с LINQ.
Сначала прочитайте ваш текстовый файл в List<string>
, используя этот код:
const string f = "TextFile1.txt";
// 1
// Declare new List.
List<string> lines = new List<string>();
// 2
// Use using StreamReader for disposing.
using (StreamReader r = new StreamReader(f))
{
// 3
// Use while != null pattern for loop
string line;
while ((line = r.ReadLine()) != null)
{
// 4
// Insert logic here.
// ...
// "line" is a line in the file. Add it to our List.
lines.Add(line);
}
}
Вам нужно определить класс, в котором у вас будет имя и, соответственно, количество:
class PersonCount
{
public string Name { get; set; }
public int Count { get; set; }
}
И, наконец, используйте это Lambda
выражение, чтобы получить желаемое List<string>
List<PersonCount> personCounts = lines.GroupBy(p => p).Select(g => new PersonCount() {Name = g.Key, Count = g.Count()}).ToList();
Теперь выполните итерацию по списку, чтобы получить имена и количество дубликатов.
Ответ №3:
Использование HashMap — это решение вашей проблемы. Когда вы читаете имя, проверьте, присутствует ли уже ключ, если да, обновите его ( 1), если нет, добавьте его в свою хэш-карту.
В конце концов, все, что вам нужно сделать, это напечатать пары ключ-значение.
Ответ №4:
Храните все имена в Dictionary<string, int> names
.
Используйте что-то подобное для каждой строки:
var theName = reader.ReadLine();
names[theName] = 1;
(он должен установить значение count равным единице, если элемент не существует)
Ответ №5:
foreach (var keyvalue in File.ReadAllLines(@"C:....").GroupBy(x => x).Select(x => new { name = x.Key, count = x.Count() }))
{
Console.WriteLine(keyvalue.name ": " keyvalue.count);
}
Ответ №6:
Вы, конечно, могли бы также сделать что-то подобное (проверка ошибок опущена), используя Linq:
var names = new List<string>(
File.ReadAllText(pathToFile).Split(
Environment.NewLine.ToCharArray(),
StringSplitOptions.RemoveEmptyEntries
));
var namesAndOccurrences =
from name in names.Distinct()
select name " " names.Count(n => n == name);
foreach (var name in namesAndOccurrences)
Console.WriteLine(name);
В зависимости от размера файла может быть желательно избавиться от потока; однако это не означает, что если файл был значительно большим для памяти, которую вы должны использовать ReadLine
.
Комментарии:
1. я думаю, используя File. ReadAllLines уменьшит необходимость разделения текстовой строки.
Ответ №7:
попробуйте это автономное решение
StreamReader dr = new StreamReader(@"C:txt.txt");
string str = dr.ReadToEnd();
string[] p = str.Split(new string[] { Environment.NewLine, " " }, StringSplitOptions.RemoveEmptyEntries);
Dictionary<string, int> count = new Dictionary<string, int>();
for (int i = 0; i < p.Length; i )
{
try
{
count[p[i].Trim()] = count[p[i]] 1;
}
catch
{
count.Add(p[i], 1);
}
}