Какую коллекцию я могу использовать, когда массивы могут показаться невозможными? Должны ли данные быть неизменными и могу ли я иметь позицию? - PullRequest
2 голосов
/ 15 июля 2011

Не так давно я опубликовал вопрос о дизайнерском решении моей игры F1. Один отвечающий отметил, что я использовал Dictionary<int, Driver>, и спросил, для чего он нужен. Я использую эту коллекцию, чтобы иметь финишную позицию и пилота на этой финишной позиции. Он предложил мне использовать массивы, потому что массивы имеют индекс, который можно использовать в качестве позиции.

Не поработав некоторое время над игрой, я взял то, что оставил, и начал думать о замене моих словарей массивами. Я начал прибегать к поиску массивов и перебрасывать одну вещь в другую, и я наткнулся на сообщения здесь на SO, в некоторых блогах (http://blogs.msdn.com/b/ericlippert/archive/2008/09/22/arrays-considered-somewhat-harmful.aspx) о том, чтобы не использовать массивы (или, в действительности, в некоторых очень специфических случаях).

Вот мои вопросы:

Когда данные поступают из базы данных и используются только для сравнения и поиска данных, что лучше всего использовать? У меня есть

  • прогноз, который содержит водителей и прогнозируемую финишную позицию
  • результат, который также содержит водителей и финишную позицию
  • баллов, который содержит баллы за каждого правильно угаданного водителя в определенной финишной позиции

Данные поступают из базы данных и не должны редактироваться, добавляться или удаляться.

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

И второй вопрос касается позиций. Какую коллекцию я могу использовать, чтобы у меня были финишные позиции, возможно, без лишних затрат на использование словаря?

var prediction = new Driver[3];
            prediction[0] = new Driver(10, "Michael Schumacher");
            prediction[1] = new Driver(7, "Felipe Massa");
            prediction[2] = new Driver(8, "Jensen Button");

            var results = new Driver[3];
            results[0] = new Driver(10, "Michael Schumacher");
            results[1] = new Driver(8, "Jensen Button");
            results[2] = new Driver(9, "Fernando Alonso");

            int[] points = { 25, 18, 15, 12, 10 };

            for (int i = 0; i < prediction.Length; i++)
            {
                if (prediction[i].Equals(results[i]))
                {
                    result += points[i];
                }
            }

Ответы [ 2 ]

1 голос
/ 15 июля 2011

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

И в этом случае он в значительной степени прав. Массив - действительно лучший способ сделать это, потому что вы знаете, сколько позиций существует, и индекс действует как позиция. Он собирается использовать наименьшее количество памяти и получить максимальную производительность, и это просто. Я имею в виду, что вы могли бы также использовать List, который для этой цели на самом деле просто более интересный массив.

Могут быть случаи, когда массивы «вредны», но есть также случай, когда вы должны придерживаться простых инструментов, когда это все, что вам нужно для работы. Массивы просты, понятны и быстры. Когда все, что вам нужно, это водитель и финишная позиция, массив является идеальным инструментом.

Когда данные поступают из базы данных и используются только для сравнения и поиск данных, что лучше всего использовать? У меня есть

прогноз, который содержит водителей и прогнозируемый результат финишной позиции, который также содержит водителей и очки финишной позиции, который содержит очки для каждого правильно угаданного водителя на определенная финишная позиция

Это зависит. Вы хотите одну коллекцию, которая хранит всю эту информацию? Если вы это сделаете, предложение Джона о словаре, вероятно, ваш лучший выбор. Я подозреваю, что это будет хороший путь, потому что в одном месте есть все, что вам нужно, с чем вы можете работать.

Если вместо этого вы хотите отдельную коллекцию для каждого, то для результатов и прогнозируемых результатов вы можете просто использовать массив для каждого (так как данные идеально подходят для него). Для очков это немного отличается, потому что очки вряд ли будут идеальным набором значений индекса, и вы можете получить два результата с одинаковым счетом.

1 голос
/ 15 июля 2011

Это зависит от того, хотите ли вы проверить по позиции (например, «Кто занял третье место?») Или водителю (например, «Какую позицию занял Уилсон?»). Это также зависит от того, насколько вы заботитесь о производительности в сценарии, который звучит так, как будто это не будет иметь большого значения для вашего приложения в целом.

Как правило, словарь будет полезен для поиска. Однако, если диапазон ключей известен, мал и непрерывен («гоночная позиция» соответствует всем трем критериям), тогда словарь не предлагает ничего, кроме массива (и имеет больше накладных расходов). Поэтому, если вы хотите выполнить запрос по позиции, используйте массив, потому что это самый простой инструмент, который соответствует описанию работы.

Если вы хотите сделать запрос по драйверу, то сначала вы должны ответить на вопрос "как точно определяется личность Driver?" (ответом может быть «каждый водитель уникально идентифицируется по своей фамилии, имени и дате рождения»).

Затем вы можете заставить класс Driver реализовать IEquatable<Driver>, используя эти критерии, и поместить его в Dictionary<Driver, Positions>, где я использую класс ниже, чтобы избежать нескольких словарей.

class Positions
{
    public int Predicted { get; set; }
    public int Actual { get; set; }
}

Тем не менее, вы должны спросить себя, есть ли смысл идти ко всем этим неприятностям вместо того, чтобы иметь массив, например. Tuple<Driver, Positions> и цикл по массиву, чтобы найти драйвер, который вы хотите каждый раз. Это может показаться неэффективным в теории, но если у вас есть только 20 драйверов, это будет намного быстрее, чем словарь.

Наконец, я не вижу необходимости в том, чтобы пометить эти структуры данных как неизменяемые и / или обеспечить неизменность. Поскольку ваше приложение работает в режиме только для чтения и не содержит кода, который пытается отправить данные обратно в базу данных, я думаю, что совершенно очевидно, что бессмысленно изменять данные в коде.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...