Использование StreamReader для подсчета дубликатов?

#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);
    }
}