Any other ways to emulate `tr` in J?
Asked Answered
T

4

7

I picked up J a few weeks ago, about the same time the CodeGolf.SE beta opened to the public.

A recurrent issue (of mine) when using J over there is reformatting input and output to fit the problem specifications. So I tend to use code like this:

( ] ` ('_'"0) ) @. (= & '-')

This one untested for various reasons (edit me if wrong); intended meaning is "convert - to _". Also come up frequently: convert newlines to spaces (and converse), merge numbers with j, change brackets.

This takes up quite a few characters, and is not that convenient to integrate to the rest of the program.

Is there any other way to proceed with this? Preferably shorter, but I'm happy to learn anything else if it's got other advantages. Also, a solution with an implied functional obverse would relieve a lot.

Transmarine answered 4/3, 2011 at 22:18 Comment(0)
R
6

It sometimes goes against the nature of code golf to use library methods, but in the string library, the charsub method is pretty useful:

   '_-' charsub '_123'
 -123
   ('_-', LF, ' ') charsub '_123', LF, '_stuff'
 -123 -stuff
Resolutive answered 5/3, 2011 at 6:51 Comment(3)
It's all fair to me if it comes with the default environment :-) Are those libraries documented anywhere? I keep searching for them and rarely find anything interesting.Transmarine
The list of libraries is strewn about. You want to have a good look at the this page on their wiki. Your best friend is still opening a library script and looking at the comments therein. Try open 'strings'.Resolutive
The standard library of J is documented here.Riyadh
M
4

rplc is generally short for simple replacements:

  'Test123' rplc 'e';'3'
  T3st123

Amend m} is very short for special cases:

 '*' 0} 'aaaa'
 *aaa
 '*' 0 2} 'aaaa'
 *a*a
 '*&' 0 2} 'aaaa'
 *a&a

but becomes messy when the list has to be a verb:

b =: 'abcbdebf'
'L' (]g) } b
aLcLdeLf

where g has to be something like g =: ('b' E. ]) # ('b' E. ]) * [: i. #.

There are a lot of other "tricks" that work on a case by case basis. Example from the manual:

To replace lowercase 'a' through 'f' with uppercase 'A' through 'F' in a string that contains only 'a' through 'f': ('abcdef' i. y) { 'ABCDEF' Extending the previous example: to replace lowercase 'a' through 'f' with uppercase 'A' through 'F' leaving other characters unchanged: (('abcdef' , a.) i. y) { 'ABCDEF' , a.

Mooned answered 6/3, 2011 at 20:8 Comment(0)
P
1

I've only dealt with the newlines and CSV, rather than the general case of replacement, but here's how I've handled those. I assume Unix line endings (or line endings fixed with toJ) with a final line feed.

  • Single lines of input: ".{:('1 2 3',LF) (Haven't gotten to use this yet)
  • Rectangular input: (".;._2) ('1 2 3',LF,'4 5 6',LF)
  • Ragged input: probably (,;._2) or (<;._2) (Haven't used this yet either.)
  • One line, comma separated: ".;._1}:',',('1,2,3',LF)

This doesn't replace tr at all, but does help with line endings and other garbage.

Praetorian answered 23/3, 2011 at 16:9 Comment(2)
I've developed a few tricks for line endings over the years, namely -. CR to remove all carriage returns and leave only LF, then cut from string.ijs (or your mention of ;._2) works well too and will do empties if you need them.Resolutive
Also, iso dates (YYYY-MM-DD hh:mm:ss) to ints: ". '- : ' charsub thedate.Resolutive
I
1

You might want to consider using the 8!:2 foreign:

   8!:2]_1
-1
Intensifier answered 25/3, 2011 at 13:32 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.