如何使用 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│
└───┴───┴────┴─────┴──────┴──────┴───────┴────────┘
我已经习惯了按 操作排序,许多语言都支持这种操作。它需要一些比较器并按它排序。 我想做的是先按长度对下面的单词进行排序,然后再按字母顺序排序。请帮助我。
我在 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│
└───┴───┴────┴─────┴──────┴──────┴───────┴────────┘