2016-03-21 2 views
1

Я привык к сортировать по операции, которую предоставляют многие языки. Для этого требуется некоторый компаратор и сортировка. Что я хочу сделать, так это отсортировать следующие слова: по длине, а затем по заказу. Помоги мне, пожалуйста.Как сортировать с помощью J

Я ничего не нашел в Фразах или Словаре на jsoftware, кроме как для сортировки и оценки числовых значений.

words=: >;:'CLOUD USB NETWORK LAN SERVER FIREWIRE CLIENT PEER' 
    ] alpha=: a. {~ (i.26) + a.i.'A' 
ABCDEFGHIJKLMNOPQRSTUVWXYZ 
    ;/ words/: alpha i. words 
┌────────┬────────┬────────┬────────┬────────┬────────┬────────┬────────┐ 
│CLIENT │CLOUD │FIREWIRE│LAN  │NETWORK │PEER │SERVER │USB  │ 
└────────┴────────┴────────┴────────┴────────┴────────┴────────┴────────┘ 

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

ABC 
DEFG 
    XY 

Тогда для пробельных назначить крайнее ранжирование (в у аргумент сортировки примитивным). И затем сдвиньте каждое слово назад :D. Это было бы очень неэффективно, я не вижу другого J-way.

Update
Вот Wolfram Язык код для моей проблемы:

StringSplit @ "CLOUD USB NETWORK LAN SERVER FIREWIRE CLIENT PEER" 
~SortBy~ 
(Reverse @ ComposeList[{StringLength}, #] &) 

Если я хочу установить приоритеты более длинные слова, я просто добавить Minus @* к StringLength. В основном мой порядок сортировки здесь {{5, "CLOUD"}, {3, "USB"}, {7, "NETWORK"}, ...}.

Я могу сделать тот же массив в J, используя (,.~ #&.>), применяемый к коробочным словам, но как я могу использовать примитивы сортировки? Может быть, это правильный первый шаг? Я все еще не уверен, но это звучит намного лучше, чем мое первое предположение :).

ответ

1

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

Прежде всего, я не думаю, что это хорошая идея применить > к списку слов, потому что это добавит заливку, которая уничтожает информацию о длине каждого слова. Так что начните с

words=: ;:'CLOUD USB NETWORK LAN SERVER FIREWIRE CLIENT PEER' 

Тогда вам нужна функция Foo, который превращает каждое слово в значение, которое будет сортировать в порядке, вы хотите с помощью \: или /:

words \: foo words 

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

(/: foo) words 

Моего оригинальное предложение для Foo используется #. чтобы выразить каждое слово как один номер:

foo=: (128&#.)@(a.&i.)@> 
    foo words 
18145864388 1403330 345441182148939 1253582 2870553715410 39730390339053893 2322657797972 168911570 

    (/: foo) words 
┌───┬───┬────┬─────┬──────┬──────┬───────┬────────┐ 
│LAN│USB│PEER│CLOUD│CLIENT│SERVER│NETWORK│FIREWIRE│ 
└───┴───┴────┴─────┴──────┴──────┴───────┴────────┘ 

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

(/: (# , a.&i.)@>) words 
┌───┬───┬────┬─────┬──────┬──────┬───────┬────────┐ 
│LAN│USB│PEER│CLOUD│CLIENT│SERVER│NETWORK│FIREWIRE│ 
└───┴───┴────┴─────┴──────┴──────┴───────┴────────┘ 
+0

ОК, я придумал подходящий foo. Вот функция g, которая превращает каждое слово в число с использованием базы 128 (потому что я принимаю символы ascii).Естественно, что более длинные слова имеют большие значения, но в пределах длины имеет значение только порядок символов. g =: monad: '128 #. а. я. y ' (/: g @>) слова ─────┐ ──────────────────────────────────────────── –

+0

Мой браузер не очень хорошо взаимодействует с этими формами. Определение g должно быть в отдельной строке g =: monad: '128 #. а. я. y ' –

+0

Затем foo определяется как g @> –