Mailing List Archive: 49091 messages
  • Home
  • Script library
  • AltME Archive
  • Mailing list
  • Articles Index
  • Site search
 

Bidirectional value mapping.

 [1/13] from: bga::bug-br::org::br at: 3-Nov-2003 15:07


Hello. I have 2 values that would be mapped to each other. What I need to do is to be able to find the first valeu by searching for the ceond and locate the second by searching for the first. I did come up with solutions to that but I am not satisfied with any of the solutions. Is there a standard Rebol-Way ofr doing that? The best option would be a way that would not result in data duplication. -Bruno

 [2/13] from: maximo:meteorstudios at: 3-Nov-2003 11:52


liquid. that is its main purpose. it is also linked to vid via liquid-vid. development has slown down for a few weeks, but it'll pick up. http://www.rebol.it/~steel a working version and some documentation can be found here: http://www.rebol.it/~steel for an understanding of liquid itself, you should test out liquid-vid. 90% of it is a direct extension of liquid (concept, nomenclature, functioning, etc). you can validate data localy to each but the actual storage is shared. if you really want to could create a container, which actually stores a copy of the value locally to an object (in an altered state?). HTH ciao! -MAx ------------- Steel project coordinator http://www.rebol.it/~steel

 [3/13] from: patrick:philipot:laposte at: 3-Nov-2003 18:33


Hi Bruno, You can use 'select with a little trick
>> firstvalue: 1
== 1
>> secondvalue: 2
== 2
>> searchblock: reduce [firstvalue secondvalue firstvalue]
== [1 2 1]
>> select searchblock firstvalue
== 2
>> select searchblock secondvalue
== 1
>> select searchblock firstvalue
== 2
>> select searchblock secondvalue
== 1 Regards Patrick

 [4/13] from: apwing:zonnet:nl at: 3-Nov-2003 18:57


Hi bruno, do you mean something like the ALIAS function? http://www.rebol.com/docs/words/walias.html If not, can you supply some code, an example? Met vriendelijke groet / with kind regards, Arie van Wingerden http://home.zonnet.nl/rebolution ICQ 343101686 ----- Original Message ----- From: Bruno G. Albuquerque To: [rebol-list--rebol--com] Sent: Monday, November 03, 2003 6:07 PM Subject: [REBOL] Bidirectional value mapping. Hello. I have 2 values that would be mapped to each other. What I need to do is to be able to find the first valeu by searching for the ceond and locate the second by searching for the first. I did come up with solutions to that but I am not satisfied with any of the solutions. Is there a standard Rebol-Way ofr doing that? The best option would be a way that would not result in data duplication. -Bruno

 [5/13] from: bga:bug-br at: 3-Nov-2003 17:12


Hello Arie. Thanks but this is not what I was looking for. Patrick nailed it though (although his solution results in data duplication). See my previous email. -Bruno Arie van Wingerden disse:

 [6/13] from: bga:bug-br at: 3-Nov-2003 17:11


Hello Patrick. Thanks! This works great (although there is data duplication). It even works in a case like this:
>> firstvalue:1
== 1
>> secondvalue: 2
== 2
>> thirdvalue: 3
== 3
>> fourthvalue: 4
== 4
>> test: [ 1 2 1 3 4 3 ]
== [1 2 1 3 4 3]
>> select teste 1
== 2
>> select teste 2
== 1
>> select teste 3
== 4
>> select teste 4
== 3 It looks select just returns after the first occurence of the data being searched with, in this case, is a good thing. -Bruno

 [7/13] from: joel:neely:fedex at: 3-Nov-2003 12:56


Hi, Bruno, I know of no way to avoid some duplication. See below. Bruno G. Albuquerque wrote:
> I have 2 values that would be mapped to each other. What I need to do is > to be able to find the first valeu by searching for the ceond and locate > the second by searching for the first. I did come up with solutions to > that but I am not satisfied with any of the solutions. Is there a standard > Rebol-Way ofr doing that? The best option would be a way that would not > result in data duplication. >
The answer somewhat depends on details of your problem; if "forward" and "reverse" mappings are distinct (as in translating between host names and IP addresses, or encoding and decoding with a non-symmetric encryption scheme) then the simplest thing to do is keep both maps as separate blocks (or hashes):
>> roman2number: ["i" 1 "v" 5 "x" 10 "l" 50 "c" 100]
== ["i" 1 "v" 5 "x" 10 "l" 50 "c" 100]
>> number2roman: [1 "i" 5 "v" 10 "x" 50 "l" 100 "c"]
== [1 "i" 5 "v" 10 "x" 50 "l" 100 "c"]
>> select roman2number "x"
== 10
>> select number2roman 10
== "x" If you know which "way" you're mapping, you just select the appropriate map. (Of course, it's easy to write a function that would take one of the above and give the other, so you don't have to create both by hand.) NOTE!!! That last sentence is only true if the mapping is an invertable function!!! If, instead, you have a many-to-one (e.g. letters to the words "consonant" or "vowel") of course there's no way to invert. I assume you know that, but want to include that warning for completeness. The other (perhaps slightly more "REBOLish") way to do this is to inter- leave the forward and reverse mapping values as follows:
>> roman-numerals: [
"i" 1 "i" "v" 5 "v" "x" 10 "x" "l" 50 "l" "c" 100 "c" ] == ["i" 1 "i" "v" 5 "v" "x" 10 "x" "l" 50 "l" "c" 100 "c"]
>> select roman-numerals "x"
== 10
>> select roman-numerals 10
== "x" This works nicely for such things as ROT13, which is a self-inverse mapping (and again, you can write a utility function that would take e.g. ROMAN2NUMBER above and give you the interleaved ROMAN-NUMERALS). However THIS DOES NOT WORK IN GENERAL if the domain and range of your mapping overlap. As a simple example, consider the trivial example of rotating among three elements: forward: ["a" "b" "c" "a"] reverse: ["c" "b" "a" "c"] Since "a" maps to "b" going forward, but "b" maps to "c" going forward, then both forward and reverse mappings can't be combined into a single block/hash. To see why this is true, consider what would have to follow b in the combined series! Unless you know you have a self-inverse mapping and you consider speed soooooo important that you'll sacrifice readability for performance, I recommend using distinct forward/reverse mappings (with a helper to construct the inverted one). It'll be easier to read anyway! -jn- -- ---------------------------------------------------------------------- Joel Neely joelDOTneelyATfedexDOTcom 901-263-4446 Enron Accountingg in a Nutshell: 1c=$0.01=($0.10)**2=(10c)**2=100c=$1

 [8/13] from: bga:bug-br at: 3-Nov-2003 18:01


Hello Joel. That's what I call a complete explanation. Thanks! I decided to use the interleaved values option. The reason I need something like what I described is that I am creating a HTTP Proxy using Rebol (that will eventually evolve into an HTTP Tunnel application). The mapping is used to map the incoming port to the outgoing one as I have data arriving and leaving from both ports so I need a way to determine where I have to send the data I just received in a specific port. BTW, the reason I am doing this HTTP proxy is because I need NTLM authentication. I already have all the NTLM stuff working (including DES encryption by loading the OpenSSL library and using it) under Rebol and I am now doing the proxy itself. Joel Neely disse:

 [9/13] from: rotenca:telvia:it at: 3-Nov-2003 21:04


Hello.
> I have 2 values that would be mapped to each other. What I need to do is > to be able to find the first valeu by searching for the ceond and locate > the second by searching for the first. I did come up with solutions to > that but I am not satisfied with any of the solutions. Is there a standard > Rebol-Way ofr doing that? The best option would be a way that would not > result in data duplication.
If values are in a block:
>> select [a 1] 'a
== 1
>> first back find [a 1] 1
== a the last can be wrapped by a function which tests the existence of the value. bselect: func [blk value][ if blk: find blk value [pick blk -1] ] --- Ciao Romano

 [10/13] from: Christian:Ensel:GMX at: 3-Nov-2003 21:10


Hi Bruno, doing it in the SELECT-way is nice but you should consider using it with the /SKIP-refinement. Without this you may end up with surprising results if one value may occur in value-1 and value-2 position as in ;------------------------------------
>> that's-life: [cats birds cats birds insects birds] >> who-hunts?: func ['animal] [select that's-life animal] >> who-hunts? birds
== cats
>> who-hunts? insects
== birds
>> prey-of?: func ['animal] [select that's-life animal] >> prey-of? cats
== birds
>> prey-of? birds
== cats ; OOPS! ;------------------------------------ The following design doesn't suffer from this difficulty and avoids duplication of values, too, at the cost of a little bit more maintenance work: ;------------------------------------ color-names: [red green blue] color-values: [255.0.0 0.255.0 0.0.255] select-color-by-name: func [name [word!] /local color] [ if color: find color-names name [pick color-values index? color] ] select-color-by-values: func [value [tuple!] /local color] [ if color: find color-values value [pick color-names index? color] ] append-color: func [name [word!] value [tuple!]] [ append color-names color append color-values color ] remove-color: func [name [word!] value [tuple!]] [ remove find color-names name remove find color-values value ] ;------------------------------------ A lot of improvements can be made to this, especially the REMOVE-COLOR is somewhat bad designed in respect to data-integrity (try REMOVE-COLOR RED 0.255.0 - Hey, I'm color-blind ;-) But what I like about the design this approach that it is easily expandable in cases you have to deal with tuples of data of length greater than just 2. HTH, Christian

 [11/13] from: maximo:meteorstudios at: 3-Nov-2003 16:07


Hi Bruno, I'm sorry If I have induced you into error, but I did not understand the question in the proper way... If you want to map a series of values to-from, then liquid isn't really the thing to use... I thought you meant to keep a synchronisation between to entities... so that a change in one repercutes as a change to the other... But, just using select a reverse on a series, makes it map one value to another, if you want to map the other way, you need to use reverse (but, of course, you need to know the direction of the search): list: ["a" 1 "b" 2 "c" 3] select list "b" ==2 select (head reverse copy list) 2 == b note that the parentheses aren't necessary, I just added them to increase readability. I've read that they can affect performance, so they should be removed when used in real code. HTH -MAx --- You can either be part of the problem or part of the solution, but in the end, being part of the problem is much more fun.

 [12/13] from: g:santilli:tiscalinet:it at: 4-Nov-2003 10:53


Hi Bruno, On Monday, November 3, 2003, 9:01:44 PM, you wrote: BGA> I decided to use the interleaved values option. The reason I need BGA> something like what I described is that I am creating a HTTP Proxy using BGA> Rebol (that will eventually evolve into an HTTP Tunnel application). The BGA> mapping is used to map the incoming port to the outgoing one as I have BGA> data arriving and leaving from both ports so I need a way to determine BGA> where I have to send the data I just received in a specific port. You could have the other port in port/userdata. I.e.: ; someone connects in-port: first listen ; ... ; you open your port out-port: open ... ; set up the relationship out-port/userdata: in-port in-port/userdata: out-port ; ... ; now if you receved data on PORT insert port/userdata copy port ; the above works for both ports This is just to give you some ideas. Regards, Gabriele. -- Gabriele Santilli <[g--santilli--tiscalinet--it]> -- REBOL Programmer Amiga Group Italia sez. L'Aquila --- SOON: http://www.rebol.it/

 [13/13] from: robert:muench:robertmuench at: 8-Nov-2003 18:25


On Mon, 3 Nov 2003 18:01:44 -0200 (BRST), Bruno G. Albuquerque <[bga--bug-br--org--br]> wrote:
> BTW, the reason I am doing this HTTP proxy is because I need NTLM > authentication. I already have all the NTLM stuff working (including DES > encryption by loading the OpenSSL library and using it) under Rebol and I > am now doing the proxy itself.
Hi, NTLM authentification? That's very interesting. I once had a Python script that worked the same way as a localhost proxy to give non-NTLM-aware applications access to it. IIRC the Python solution didn't required OpenSSL, it was all done in Python. One other thing comes to mind: Do you know http://www.htthost.com ? Robert