############################################################################ # # 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