1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
|
############################################################################
#
# File: mapstr.icn
#
# Subject: Procedure for map() for strings
#
# Author: Richard L. Goerwitz
#
# Date: March 3, 1996
#
############################################################################
#
# This file is in the public domain.
#
############################################################################
#
# Version: 1.1
#
############################################################################
#
# Mapstrs(s, l1, l2) works like map(), except that instead of taking
# ordered character sequences (strings) as arguments 2 and 3, it
# takes ordered string sequences (lists).
#
# Suppose, for example, you wanted to bowdlerize a string by
# replacing the words "hell" and "shit" with "heck" and "shoot." You
# would call mapstrs as follows:
#
# mapstrs(s, ["hell", "shit"], ["heck", "shoot"])
#
# In order to achieve reasonable speed, mapstrs creates a lot of
# static structures, and uses some extra storage. If you want to
# replace one string with another, it is overkill. Just use the IPL
# replace() routine (in strings.icn).
#
# If l2 is longer than l1, extra members in l2 are ignored. If l1 is
# longer, however, strings in l1 that have no correspondent in l2 are
# simply deleted. Mapstr uses a longest-possible-match approach, so
# that replacing ["hellish", "hell"] with ["heckish", "heck"] will
# work as one would expect.
#
############################################################################
#
# Links: longstr
#
############################################################################
link longstr
procedure mapstrs(s, l1, l2)
local i, s2
static cs, tbl, last_l1, last_l2
if /l1 | *l1 = 0 then return s
if not (last_l1 === l1, last_l2 === l2) then {
cs := ''
every cs ++:= (!l1)[1]
tbl := table()
every i := 1 to *l1 do
insert(tbl, l1[i], (\l2)[i] | "")
}
s2 := ""
s ? {
while s2 ||:= tab(upto(cs)) do
s2 ||:= tbl[tab(longstr(l1))] | move(1)
s2 ||:= tab(0)
}
return s2
end
|