Способы сортировки массива Unity C#

Привет, в основном у меня есть инвентарь в слотах Struct: Inventory Slot[]. Что я хочу сделать, это отсортировать массив в зависимости от вида инвентаря. Я не хочу преобразовывать его в список, так как практически весь мой код основан на массивах, и все подключено и работает хорошо. Я перепробовал много способов, просмотрел все видео на YouTube о сортировке инвентаря.

Один из лучших способов, которые я создал:

Я попытался создать вторичный массив:

private void Awake()
        {
           slots = new InventorySlot[inventorySize];
           slotList = new InventorySlot[inventorySize];
        }

public void SortByTypeNameAscending()
        {
            var SortedSlots = slotList.Where(t => t.item != null).OrderBy(t => t.item.GetAllowedEquipLocation()).ToArray();

            slots = SortedSlots;
            inventoryUpdated?.Invoke();
        }

Когда я добавляю предмет в инвентарь или удаляю его, я обновляю оба массива, выполняя: slotList = slots в функции добавления или удаления. SlotList содержит все предметы, и слоты будут меняться в соответствии с «Фильтром». Если я удаляю Where(t => t.item != null), проблема заключается в том, что если у меня есть пустые слоты, это дает мне нулевую ошибку. Пытался сделать что-то вроде InventorySlot?[] slots and slots = new InventorySlot?[inventorySize], чтобы он принимал нули, но моя функция сортировки имеет несколько ошибок. С другой стороны, когда я использую Where(t => t.item != null), если у меня есть 10 слотов, а 1/10 равно нулю, сортировка работает, но инвентарь становится инвентарем из 9 слотов вместо 10 слотов (с 1 свободный слот), и я не смогу добавить еще 1 предмет.

Я не знаю, есть ли способ обойти это, может быть, способ преобразовать его в список в самой функции и преобразовать его в массив? Есть идеи?

Вы можете использовать список для сортировки, затем добавить недостающие части в список и, наконец, преобразовать список обратно в массив. (Конечно, это возможно, если размер этих массивов невелик)

Steve 25.12.2020 00:27
var SortedSlots = slotList.OrderBy(t => t?.item?.GetAllowedEquipLocation()).ThenBy(z => z == null).ToArray(); Это делает то, что вы хотите?
mjwills 25.12.2020 00:28

@ Стив, я не могу это использовать, инвентарь будет расширяться все больше и больше. В дальнейшем это вызовет проблемы.

Patrick 25.12.2020 02:28

@mjwills Если я это сделаю, я получу ошибку на t?. Если я удалю ?, я получаю сообщение об ошибке z == null....

Patrick 25.12.2020 02:29

«Я не хочу преобразовывать его в список» - списки на самом деле поддерживаются массивами....

Mitch Wheat 25.12.2020 02:55
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
5
513
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Для инвентаря я действительно предлагаю List<InventorySlot>. Затем вы можете удалять и вставлять в список, не беспокоясь о создании нового массива или перемещении элементов.

Если вы сопоставляете инвентарь с какой-то сеткой, я предлагаю вам добавить свойство x и y в класс InventorySlot, чтобы вы могли отслеживать, где он находится в сетке инвентаря. Нет необходимости держать список отсортированным в соответствии с отображением инвентаря.

Это также сделает так, что вам не нужно хранить два списка InventorySlot элементов, вы можете просто обойтись одним списком. Когда вы собираетесь визуализировать свою сетку инвентаря, просто повторите список и нарисуйте/переместите спрайт предмета в нужное место.

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

«но тот факт, что у вас есть другие части вашей игры, знающие, что ваш инвентарь представляет собой массив, является проблемой архитектуры». +1

Mitch Wheat 25.12.2020 02:56

@jjxtra Спасибо за ответ. Поскольку мой InventorySlot был структурой, содержащей элемент и число, с массивом я обычно делал slot[i].item = X. Со списком что было бы эквивалентно slot[i].item ? или, по крайней мере, как мне получить элементы структуры со списком?

Patrick 25.12.2020 03:49

list.FirsOrDefault(l=>l.Index == x)

jjxtra 25.12.2020 19:03

Другие вопросы по теме