Page 1 of 1

How to define a Map of Arrays?

Posted: 24 Nov 2022, 09:11
by hoppfrosch
Hi there,

I want to define a map of arrays. What I currently do is following:

Code: Select all

keys := ["k1", "k2", "k3"]
data := ["d1", "d2", "d3", "d4", "d5", "d6"]

m := Map()
for k in keys {
	for d in data {
		if m.Has(k) {
			m[k].push(data[A_index])
		} else {
			m[k] := [data[A_Index]]
		}
	}
}
ExitApp
This works, but I don't like it - I want to avoid the inner "if m.Has(k) ..." conditional - in favor of a simple "m[k].push(data[A_index])"

Is there an easier way to define m as a Map, containing Arrays as data - preferred outside the for loops ...
Something like (Pseudocode):

Code: Select all

m:=Map(String, Arr(String))  # m is a map with strings as key and arrays of strings as value

Re: How to define a Map of Arrays?  Topic is solved

Posted: 24 Nov 2022, 15:52
by lexikos
You cannot "define" a map of arrays. You must create a map and map keys to values, with each value being an array. You must define the behaviour, such as whether an array is created upon access of any key or only when a value is to be inserted. You can hide this away within the Map (or subclass) by overriding __Item and methods, but it will only change the appearance of how you use the Map. The same things will be happening under the hood.

You can avoid one key lookup (in the event that there is an array already) by using Get:

Code: Select all

a := (m.Get(k, false) || m[k] := [])
a.push(data[A_Index])

Re: How to define a Map of Arrays?

Posted: 08 Dec 2022, 07:14
by ThePeter
I cannot help myself observing (EDIT: incorrectly, as it turns out) that this can be further compressed (saving a variable assignment in the process):

Code: Select all

m.Get(k, m[k] := []).push(data[A_Index])
I am fully aware that this goes into Perl / write-only territory... :)

Re: How to define a Map of Arrays?

Posted: 08 Dec 2022, 07:59
by swagfag
then observe more, because now ure unconditionally (re-)creating a new empty array. ahk uses applicative order as its evaluation strategy

Re: How to define a Map of Arrays?

Posted: 08 Dec 2022, 09:42
by Descolada
If your keys are unique then perhaps also this would work:

Code: Select all

keys := ["k1", "k2", "k3"]
data := ["d1", "d2", "d3", "d4", "d5", "d6"]

m := Map()
for k in keys {
	m[k] := []
	for d in data
		m[k].push(d)
}
ExitApp

Re: How to define a Map of Arrays?

Posted: 08 Dec 2022, 09:51
by ThePeter
swagfag wrote:
08 Dec 2022, 07:59
then observe more, because now ure unconditionally (re-)creating a new empty array. ahk uses applicative order as its evaluation strategy
Interesting. Had to look up what applicative order means, but now I have learned something. Thanks for that.

Re: How to define a Map of Arrays?

Posted: 05 Sep 2023, 13:34
by cgx5871
lexikos wrote:
24 Nov 2022, 15:52
You cannot "define" a map of arrays. You must create a map and map keys to values, with each value being an array. You must define the behaviour, such as whether an array is created upon access of any key or only when a value is to be inserted. You can hide this away within the Map (or subclass) by overriding __Item and methods, but it will only change the appearance of how you use the Map. The same things will be happening under the hood.

You can avoid one key lookup (in the event that there is an array already) by using Get:

Code: Select all

a := (m.Get(k, false) || m[k] := [])
a.push(data[A_Index])
I want to put an array arr:=[1,"a",2,"b",3,"c"]
Convert directly to map, mp:={1,"a",2,"b",3,"c"}
Any good ideas?

Re: How to define a Map of Arrays?

Posted: 05 Sep 2023, 19:28
by boiler
cgx5871 wrote: I want to put an array arr:=[1,"a",2,"b",3,"c"]
Convert directly to map, mp:={1,"a",2,"b",3,"c"}
Any good ideas?
Not sure if this question is really on topic for this thread, but I think you're looking to do this:

Code: Select all

arr := [1,"a",2,"b",3,"c"]
mp := Map()
for k, v in arr
	if Mod(k, 2)
		mp[v] := arr[k+1]

; display resulting map:
for k, v in mp
	MsgBox k ": " v

Re: How to define a Map of Arrays?

Posted: 05 Sep 2023, 20:38
by cgx5871
@boiler
I found an easy way
mp.set(arr*)

Re: How to define a Map of Arrays?

Posted: 05 Sep 2023, 20:50
by boiler
Thanks. Learned something today!

Re: How to define a Map of Arrays?

Posted: 05 Sep 2023, 22:07
by lexikos
Unless the map already exists, you could just use Map(arr*).