如何使用 J 进行排序

How to Sort By using 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

然后为空白分配极端排名(在排序原语的 y 参数中)。然后将每个单词移回:D。这将是非常低效的,我看不到另一个 J-way。

更新
这是我的问题的 Wolfram 语言 代码:

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

如果我想优先处理较长的单词,我只需将 Minus @* 附加到 StringLength。 基本上我这里的排序顺序是{{5, "CLOUD"}, {3, "USB"}, {7, "NETWORK"}, ...}.

我可以在 J 中使用 (,.~ #&.>) 应用于盒装单词来创建相同的数组,但是我该如何使用排序原语呢?也许这是正确的第一步?我仍然不确定,但听起来比我最初的猜测好得多 :)

应要求,我已将评论中建议的答案提升为答案主体。

首先,我认为将 > 应用于单词列表不是一个好主意,因为这会添加填充,从而破坏有关每个单词长度的信息。所以从

开始
   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│
└───┴───┴────┴─────┴──────┴──────┴───────┴────────┘

在评论中,Danylo Dubinin 指出,我们可以简单地将单词长度连接到索引向量的前面,然后使用它进行排序,而不是对单词进行编码:

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