Сортировка Списка <> с моим пользовательским порядком, который хранится в другом Списке (C#)?

Это работает & mdash; это не то, что я бы использовал, но это «работает». Давайте создадим скрипт teredo для установки переменной среды TEREDO_WORMS:

#!/bin/ksh
export TEREDO_WORMS=ukelele
exec $SHELL -i

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

Перед запуском этого скрипта мы установили SHELL в среде для оболочки C, а переменная среды TEREDO_WORMS не установлена:

% env | grep SHELL
SHELL=/bin/csh
% env | grep TEREDO
%

Когда скрипт запущен, вы в новой оболочке - другая интерактивная оболочка C, но установлена ​​переменная окружения:

% teredo
% env | grep TEREDO
TEREDO_WORMS=ukelele
%

При выходе из этой оболочки исходная оболочка вступает во владение:

% exit
% env | grep TEREDO
%

Среда переменная не установлена ​​в среде исходной оболочки. Если вы используете exec teredo для запуска команды, то исходная интерактивная оболочка заменяется оболочкой Korn, которая задает среду, а затем, в свою очередь, заменяется новой интерактивной оболочкой C:

% exec teredo
% env | grep TEREDO
TEREDO_WORMS=ukelele
%

Если вы наберете exit (или Control-D ), то ваша оболочка закроется, возможно, выйдет из этого окна или вернет вас на предыдущий уровень оболочки, с которого начались эксперименты.

Тот же механизм работает для оболочки Bash или Korn. Вы можете обнаружить, что подсказка после команд выхода появляется в забавных местах.


Обратите внимание на обсуждение в комментариях. Это не решение, которое я бы рекомендовал, но оно достигает заявленной цели единого сценария, чтобы установить среду, которая работает со всеми оболочками (которые принимают опцию -i для создания интерактивной оболочки). Вы также можете добавить "$@" после опции для передачи любых других аргументов, что может сделать оболочку пригодной для использования в качестве общего инструмента 'set environment and execute command'. Возможно, вы захотите опустить -i, если есть другие аргументы, приводящие к:

#!/bin/ksh
export TEREDO_WORMS=ukelele
exec $SHELL "${@-'-i'}"

Бит "${@-'-i'}" означает «если список аргументов содержит хотя бы один аргумент, используйте исходный список аргументов; в противном случае замените -i несуществующими аргументами ».

7
задан mark smith 2 July 2009 в 21:09
поделиться

3 ответа

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

class ItemTpComparer : IComparer<itemTp>
{
    private IList<codeTp> otherList;

    public ItemTpComparer(IList<codeTp> otherList)
    {
        this.otherList = otherList;
    }

    public int Compare(itemTp a, itemTp b)
    {
        return otherList.IndexOf(a.Code) - otherList.IndexOf(b.Code);
    }
}

И для выполнения сортировки:

myList.Sort(new ItemTpComparer(otherList));
9
ответ дан 7 December 2019 в 03:19
поделиться

Извините, если что-то не так, у меня здесь не установлен редактор C #, но он примерно такой:

 Array.Sort(
     itemTps, 
     delegate(ItemTp a, ItemTp b)
     {
          return secondList.IndexOf(a.Code) - secondList.IndexOf(b.Code);
     });

Примечание: это может быть не самый эффективный способ, а также отсутствует проверка, содержит ли второй список Код вообще.

[Edit] Как сказал Мердад, Array.Sort не работает для общего IList . Чтобы отсортировать массив на месте, вам нужно будет использовать метод ArrayList.Adapter , чтобы создать оболочку, а затем отсортировать ее. Поскольку ArrayList.Sort не поддерживает сравнение делегатов, вам необходимо поместить анонимный делегат в реализацию IComparer ,.

Если вам нужно его отсортировать в отдельном списке, тогда имеет смысл использовать описанную выше логику, сначала создав массив.

0
ответ дан 7 December 2019 в 03:19
поделиться

Используя C # 3 и LINQ to Objects, я бы просто создал новый список вместо того, чтобы пытаться отсортировать существующий:

void Example()
{
    IList<string> codes;
    IList<ItemTp> itemTps;
    itemTps = codes.Select(code => itemTps.Single(itp => itp.Code == code)).ToList();
}
0
ответ дан 7 December 2019 в 03:19
поделиться