我有以下(例如)数据
'a';'b';'c';'a';'b';'a'
┌─┬─┬─┬─┬─┬─┐
│a│b│c│a│b│a│
└─┴─┴─┴─┴─┴─┘
我想将所有'a'
替换为一个号码3
和'b'
替换为另一个号码4
,然后返回
┌─┬─┬─┬─┬─┬─┐
│3│4│c│3│4│3│
└─┴─┴─┴─┴─┴─┘
我该怎么做?
感谢您的帮助。
答案 0 :(得分:3)
如果那是一个字符串(如'abcaba'
),那么rplc
就会有一个简单的解决方案:
'abcaba' rplc 'a';'3';'b';'4'
34c343
}
如果你需要让它像盒装数据一样(例如,'a'表示比字符或原子更复杂的东西),那么你可以使用amend }
:
L =: 'a';'b';'c';'a';'b';'a'
p =: I. (<'a') = L NB. positions of 'a' in L
0 3 5
(<'3') p } L NB. 'amend' "3" on those positions
将上述内容纳入对话:
f =: 4 :'({.x) (I.({:x) = y) } y' NB. amend '{.x' in positions where '{:x' = y
('3';'a') f L
┌─┬─┬─┬─┬─┬─┐
│3│b│c│3│b│3│
└─┴─┴─┴─┴─┴─┘
您可以在更复杂的设置中使用
]L =: (i.5);'abc';(i.3);'hello world';(<1;2)
┌─────────┬───┬─────┬───────────┬─────┐
│0 1 2 3 4│abc│0 1 2│hello world│┌─┬─┐│
│ │ │ │ ││1│2││
│ │ │ │ │└─┴─┘│
└─────────┴───┴─────┴───────────┴─────┘
((1;2);(i.3)) f L
┌─────────┬───┬─────┬───────────┬─────┐
│0 1 2 3 4│abc│┌─┬─┐│hello world│┌─┬─┐│
│ │ ││1│2││ ││1│2││
│ │ │└─┴─┘│ │└─┴─┘│
└─────────┴───┴─────┴───────────┴─────┘
btw,{.y
是y
的第一项; {:y
是y
答案 1 :(得分:1)
这是一个可以放在工具箱中的小工具:
tr =: dyad def '(y i.~ ({." 1 x),y) { ({:" 1 x) , y'
] MAP =: _2 ]\ 'a';3; 'b';4
+-+-+
|a|3|
+-+-+
|b|4|
+-+-+
MAP tr 'a';'b';'c';'a';'b';'a'
+-+-+-+-+-+-+
|3|4|c|3|4|3|
+-+-+-+-+-+-+
实用程序tr
是一个带有两个参数(一个二元组)的动词:右边的参数是目标,左边的参数是映射表。该表必须有两列,每行代表一个映射。要只进行一次替换,可以使用两个项目的向量(即1D列表而不是2D表格,只要列表长度为两个项目。)
请注意,该表必须与目标具有相同的数据类型(因此,如果您要更换框,则必须是一个框表;如果是字符,则是字符表;数字的数字等) 。
而且,由于我们正在做类似的映射,映射表的单元格必须与目标的项目具有相同的形状,因此它不适合像字符串替换这样的任务,这可能需要变形。例如,('pony';'horse') tr 'I want a pony for christmas'
无法工作(但有趣的是,'pony horse' tr&.;: 'I want a pony for christmas'
会因为我无法进入的原因而发挥作用。
对你的问题没有人,标准答案。也就是说,翻译有一个非常常见的习惯用法(在tr
或映射1:1中):
FROM =: ;: 'cat dog bird'
TO =: ;: 'tiger wolf pterodactyl'
input=: ;: 'cat bird dog bird bird cat'
(FROM i. input) { TO
+-----+-----------+----+-----------+-----------+-----+
|tiger|pterodactyl|wolf|pterodactyl|pterodactyl|tiger|
+-----+-----------+----+-----------+-----------+-----+
要解决此问题,原始i.
是查找函数,原始{
是选择函数(助记符:i.
为您提供* i *你正在寻找的元素的索引)。
但上面简单的公式仅适用于你想要在输入中替换字面意思的所有内容,并且FROM
保证是完全的(即输入的项目被约束为FROM
中的任何内容)。
这些约束使得简单的公式适用于像字符串大小写转换的任务,你想要替换所有字母,我们事先知道字母的总体范围(即字母表是有限的)。
但是如果我们没有一个有限的宇宙会发生什么呢?我们应该如何处理未识别的物品?好吧,我们想要什么。这种灵活性的需求是J中没有单一翻译功能的原因:相反,该语言为您提供了制作特定于您需求的解决方案的工具。
例如,上面模式的一个非常常见的扩展是替换为默认值(对于无法识别的项目)的概念。并且,因为i.
被定义为在查找中找不到的项目返回1+#input
,所以扩展非常简单:我们只需将替换列表扩展一个项目,即只添加默认值!
DEFAULT =: <'yeti'
input=: ;: 'cat bird dog horse bird monkey cat iguana'
(FROM i. input) { TO,DEFAULT
+-----+-----------+----+----+-----------+----+-----+----+
|tiger|pterodactyl|wolf|yeti|pterodactyl|yeti|tiger|yeti|
+-----+-----------+----+----+-----------+----+-----+----+
当然,这是破坏性的,因为它不可逆:它没有留下关于输入的信息。有时,如你的问题,如果你不知道如何更换某些东西,最好不要管它。
同样,这种扩展非常简单,而且,一旦你看到它,显而易见:你通过附加输入来扩展查找表。这样,您就可以保证找到输入的所有项目。替换同样简单:通过附加输入来扩展替换列表。所以你最终用自己替换所有未知的物品。
( (FROM,input) i. input) { TO,input
+-----+-----------+----+-----+-----------+------+-----+------+
|tiger|pterodactyl|wolf|horse|pterodactyl|monkey|tiger|iguana|
+-----+-----------+----+-----+-----------+------+-----+------+
这是tr
中体现的策略。
tr
这样的实用程序时,J程序员通常会考虑N维案例,因为这是语言的精神。就目前而言,tr
需要一个二维映射表(并且,偶然地,它将接受两个项目的一维列表,这可能很方便)。但是有一天我们想要更换立方体内的平面,或超立方体内的立方体等(商业智能应用中常见)。我们可能希望扩展该实用程序以涵盖这些情况,如果它们出现的话。
但是怎么样?好吧,我们知道映射表必须至少有两个维度:一个用于保存多个同时替换,另一个用于保存替换规则(即一个&#34; row&#34;每个替换和两个&#34;列&#34;标识项目及其替代品)。这里的关键是我们需要的所有。为了概括tr
,我们只需说我们不关心这些维度下的内容。它可以是单个字符的Nx2表,或固定长度字符串的Nx2表,或者用于某些线性代数目的的Nx2矩阵表,或者......谁在乎呢?不是我们的问题。我们只关心框架而不是内容。
所以,让我们在tr
:
NB. Original
tr =: dyad def '(y i.~ ({." 1 x),y) { ({:" 1 x) , y'
NB. New, laissez-faire definition
tr =: dyad def '(y i.~ ({."_1 x),y) { ({:"_1 x) , y'
正如你所看到的那样,税收变化;)。不太明显:排名运算符"
可以采取正面或负面的论点。正参数允许动词处理其输入的内容,而负参数允许动词处理其输入的 frame 。在这里,"1
(正面)将{.
应用于x
的行,而"_1
(负面)将其应用于&#34;行&#34; x
,其中&#34;行&#34;在恐慌引用中,简单地表示沿着第一维的项目,即使它们恰好是37维超矩形。谁在乎?
tr
的原始定义让最懒的程序员写('dog';'cat') tr ;: 'a dog makes the best pet'
而不是(,:'dog';'cat') tr ;: 'a dog makes the best pet'
。也就是说,原始的tr
(完全意外地)允许一个简单的列表作为映射表,当然它不是一个Nx2表,即使是抽象的虚拟意义上(因为它没有至少两个维度)。也许我们想保留这种便利。如果是这样,我们必须代表用户宣传堕落的论点:
tr =: dyad define
x=.,:^:(1=#@$) x
(y i.~ ({."_1 x),y) { ({:"_1 x) , y
)
毕竟,懒惰是prime virtue of a programmer。
答案 2 :(得分:0)
这是我能想到的最简单的方法来实现你所要求的:
(3;3;3;4;4) 0 3 5 1 4} 'a';'b';'c';'a';'b';'a'
┌─┬─┬─┬─┬─┬─┐
│3│4│c│3│4│3│
└─┴─┴─┴─┴─┴─┘
这是另一种方法
(<3) 0 3 5} (<4) 1 4} 'a';'b';'c';'a';'b';'a'
┌─┬─┬─┬─┬─┬─┐
│3│4│c│3│4│3│
└─┴─┴─┴─┴─┴─┘
假设,您可能想要推广这种表达方式,或者您可能想要一种替代方案。我认为这里的其他海报已经指出了这样做的方法。 。但有时只看到最简单的形式会很有趣吗?
顺便说一句,这是我如何得到我的上述指数(删除了一些但不是所有的无关紧要):
I. (<'a') = 'a';'b';'c';'a';'b';'a'
0 3 5
('a') =S:0 'a';'b';'c';'a';'b';'a'
1 0 0 1 0 1
('a') -:S:0 'a';'b';'c';'a';'b';'a'
1 0 0 1 0 1
I.('a') -:S:0 'a';'b';'c';'a';'b';'a'
0 3 5
I.('b') -:S:0 'a';'b';'c';'a';'b';'a'
1 4