C # Как я должен собирать данные из объекта в другой экземпляр?

#c# #class #collections

#c# #класс #Коллекции

Вопрос:

У меня есть мой основной класс объектов, который содержит данные игрока: имя, счет и команду. У меня есть другой класс контейнера, в который я помещаю всех этих игроков. Я выполняю с ними некоторые действия, например, нахожу, у кого больше очков и т. Д. И Все в порядке, Но. Каким-то образом мне нужно составить список всех содержащих команд и подсчитать количество очков, набранных каждой командой. Я хотел бы спросить, каковы некоторые методы, чтобы сделать это правильно? Потому что у всех игроков могут быть разные команды или одна и та же команда, поэтому это нужно делать без дубликатов.

Я попытался сделать

 private string[] Team;
  

в моем классе контейнера, но понял, что это будет адская работа, а также то, что сделает мой класс не контейнерным.

Вот как выглядят мои классы (я помещаю только их части, а не полный класс, потому что я думаю, что в этом нет необходимости) без каких-либо изменений, которые я пробовал:

 class Player
{
        private string name;
        private string team;
        private int score;       
}

class Container
{
        const int Cn = 500;

        private Player[] Pl;

        public int Count { get; set; }

        public Container()
        {
            Count= 0;
            Pl = new Player[Cn];

        }
}
  

Итак, допустим, у меня есть 2 объекта в моем контейнере. Данные, которые они содержат, являются:

 Name    Score    Team
Matt     15      Alfa
Oreo     5       Beta
Bean     7       Alfa
  

Я хочу, чтобы результаты были:

 List of teams and their score:
Alfa     22
Beta      5
  

Комментарии:

1. Первое, на что я бы, вероятно, обратил внимание, это группировка LINQ с помощью Sum()

2. Есть ли причина сделать приватными свойства класса player

Ответ №1:

Вот одно из решений, которое использует Linq GroupBy и Sum. Я внес небольшие изменения в ваши Player Container классы и, как вы видите (1) List<Player> как хранилище данных вместо массива и (2) общедоступные свойства в Player классе:

 class Player
{
    public string Name { get; set; }
    public string Team { get; set; }
    public int Score { get; set; }
}

class Container
{
    private IList<Player> _players;
    public Container()
    {
        _players = new List<Player>();
    }    

    public void Add(Player p) => _players.Add(p);

    public IList<(string Team, int Sum)> GetTeamStats()
    {
        return _players
            .GroupBy(g => g.Team)
            .Select(r => ( Team : r.Key, Sum : r.Sum(s => s.Score)))
            .ToList();
    } 
}

class Program
{
     static void Main(string[] args)
    {
        var cont = new Container();

        cont.Add(new Player { Name = "Matt", Score = 15, Team="Alfa" });
        cont.Add(new Player { Name = "Oreo", Score = 5, Team = "Beta" });
        cont.Add(new Player { Name = "Bean", Score = 7, Team = "Alfa" });

        var teamStats = cont.GetTeamStats();
        foreach (var team in teamStats)
        {
            Console.WriteLine($"{team.Team} {team.Sum}");
        }
    }
}
  

Вывод:

 Alfa 22 
Beta 5
  

Комментарии:

1. Очень признателен за вашу помощь, это кажется оптимальным вариантом, но поскольку я делаю это для домашней работы и пытаюсь учиться сам, нет ли более простого решения моей проблемы?

2. Я не могу представить себе более простого и элегантного решения 🙂 с этим ответом вы узнаете очень хорошие приемы C # (группировка Linq, функция суммирования, именованные кортежи, основные операции со списками). Скопируйте это на свой домашний компьютер, отладьте его, измените, если, улучшите и наслаждайтесь знакомством с C # 🙂

3. @GoodnightJess, который вы узнаете LINQ , — это очень простой навык, который нужно освоить, C# если вы планируете делать что-то за пределами начального уровня. Я лично предпочитаю синтаксис запроса