Find object value in nested objects Topic is solved

Get help with using AutoHotkey (v1.1 and older) and its commands and hotkeys
Ernestas
Posts: 33
Joined: 16 Apr 2018, 02:07

Find object value in nested objects

16 Jul 2020, 04:28

Hello guys!

I was creating some nested objects and was wondering if there any shorter ways to get values from objects than this?

Code: Select all

#z::
carObj := [{"model" : ["BMW", "Tesla", "Audi", "Kia"]},{"color" : ["blue", "red", "yellow"]}]

; lets say you want to check if there is Kia in model and if you get modelToFind and objParam only in variable as below:

modelToFind := "Kia"
objParam := "model"

foundModel := 0
for index, value in carObj
{
	for carParamName, data in value 
	{
		if (carParamName = objParam)
		{			
			for key, model in data 
			{
				if (model = modelToFind)
				{
					foundModel := 1
				}
			}
		}
	}
}

MsgBox, % foundModel
return

Thank you for your time and answers in advance!
User avatar
boiler
Posts: 17387
Joined: 21 Dec 2014, 02:44

Re: Find object value in nested objects

16 Jul 2020, 05:16

Code: Select all

carObj := [{"model" : ["BMW", "Tesla", "Audi", "Kia"]},{"color" : ["blue", "red", "yellow"]}]
modelToFind := "Kia"
objParam := "model"

foundModel := 0
for key, obj in carObj
	if obj[objParam]
		for each, item in obj[objParam]
			if (item = modelToFind)
				foundModel := 1

MsgBox, % foundModel
return
Ernestas
Posts: 33
Joined: 16 Apr 2018, 02:07

Re: Find object value in nested objects

16 Jul 2020, 05:26

Hey,

thank you for your answer but its almost the same length as mine.

I was wonder if there is some solution like:

Code: Select all

for key, value in carObj.objParam ; I couldn't find a way to get variable in objParam position
	if (model = modelToFind)
	{
		foundModel := 1
	}
any thoughts or is it not possible? :o
User avatar
boiler
Posts: 17387
Joined: 21 Dec 2014, 02:44

Re: Find object value in nested objects  Topic is solved

16 Jul 2020, 05:40

If you set up your object to remove the unnecessary simple array with integer keys, then it's simple:

Code: Select all

carObj := {"model" : ["BMW", "Tesla", "Audi", "Kia"],"color" : ["blue", "red", "yellow"]}
modelToFind := "Kia"
objParam := "model"

foundModel := 0
for each, item in carObj[objParam]
	if (item = modelToFind)
		foundModel := 1

MsgBox, % foundModel
return
Ernestas
Posts: 33
Joined: 16 Apr 2018, 02:07

Re: Find object value in nested objects

16 Jul 2020, 06:33

super helpful, thank you!! :clap: :clap: :clap:
User avatar
Chunjee
Posts: 1499
Joined: 18 Apr 2014, 19:05
Contact:

Re: Find object value in nested objects

16 Jul 2020, 09:39

perhaps just an opinion but wouldn't carObj := {"model": ["BMW", "Tesla", "Audi", "Kia"], "color": ["blue", "red", "yellow"]} make more sense?

Of course I don't know how one car can have 4 models either... that's the make... the longer I look at this the less sense it makes.
User avatar
boiler
Posts: 17387
Joined: 21 Dec 2014, 02:44

Re: Find object value in nested objects

16 Jul 2020, 09:48

@Chunjee - It looks like your suggested object is the same as what I have shown.
User avatar
Chunjee
Posts: 1499
Joined: 18 Apr 2014, 19:05
Contact:

Re: Find object value in nested objects

16 Jul 2020, 10:22

Ah I see. Thanks.

Best I could come up with:

Code: Select all

A := new biga() ; requires https://www.npmjs.com/package/biga.ahk

carObj := {"model": ["BMW", "Tesla", "Audi", "Kia"], "color": ["blue", "red", "yellow"]}
modelToFind := "Kia"
objParam := "model"

msgbox, % A.includes(carObj[objParam], modelToFind)
; => 1

msgbox, % A.includes(carObj[objParam], "Toyota")
; => 0

msgbox, % A.findIndex(carObj[objParam], modelToFind)
; => 4
exitapp
4 being the index of the "Kia" in the array.


Slightly more useful in my mind... Find all the blue cars:

Code: Select all

A := new biga() ; requires https://www.npmjs.com/package/biga.ahk

carObj := {"model": ["BMW", "Tesla", "Audi", "Kia"], "color": ["blue", "red", "yellow"]}
carsArray := [{"model": ["Accord"], "color": ["blue"]}
			, {"model": ["Xterra"], "color": ["silver", "black"]}]
carsArray.push(carObj)

valueToFind := "blue"
objParam := "color"

matches := A.filter(carsArray, Func("fn_filter1"))
; => [{"color":["blue"], "model":["Accord"]}
; 	, {"color":["blue", "red", "yellow"], "model":["BMW", "Tesla", "Audi", "Kia"}]
exitapp

fn_filter1(param_interatee) {
	global objParam, valueToFind
    if (biga.indexOf(param_interatee[objParam], valueToFind) != -1) { 
        return true
    }
	return false
}
Last edited by Chunjee on 16 Jul 2020, 12:42, edited 1 time in total.
teadrinker
Posts: 4412
Joined: 29 Mar 2015, 09:41
Contact:

Re: Find object value in nested objects

16 Jul 2020, 11:21

I would suggest something like this:

Code: Select all

carObj := {"model": ["BMW", "Tesla", "Audi", "Kia"], "color": ["blue", "red", "yellow"]}

MsgBox, % ObjSearch(carObj, value, "model")
MsgBox, % ObjSearch(value, "Kia")

ObjSearch(obj, ByRef value, key := "") {
   for k, v in obj {
      if (key != "" && k = key) {
         value := v
         Return true
      }
      if (key = "" && v = value)
         Return true
      if IsObject(v) && %A_ThisFunc%(v, value, key)
         Return true
   }
}

Return to “Ask for Help (v1)”

Who is online

Users browsing this forum: Kodakku and 388 guests