how to make my dicitionary simpler

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By Mani Vannan

hi everyone!
i am new to coding so i get weird questions,
please help me to solve the problems,
thank you in advance

i dont know how to add picture of output here so i tried my best to put in words

my node structure

control #control node
    left  #button
    right  #button
    item_text #label
    input_value  #spin_box
    add  #button
    fruits   #label
    vegetables   #label
    meat   #label
    fish   #label

here is my example script

extends Control

onready var item_text = get_node("item_text")
onready var input_value = get_node("input_value")

var items_array = ["fruits", "vegetables", "meat", "fish"]   #array for text

var items = {"fruits" : 0, "vegetables" : 0, "meat" : 0, "fish" : 0}   #dictionary to store values

var id = 0  #for calling out the items_array

func _ready():
	item_update()
	items_stored_text()


func items_stored_text():  #texts for the items value or (print)
	get_node("fruits").set_text("fruits"  + "=" + str(items["fruits"]))
	get_node("vegetables").set_text("vegetables"  + "=" + str(items["vegetables"]))
	get_node("meat").set_text("meat"  + "=" + str(items["meat"]))
	get_node("fish").set_text("fish" + "=" + str(items["fish"]))

func item_update():  #setting the text from item_array
    	item_text.set_text(str(items_array[id]))  #id changes below

func _on_left_pressed():    # <  id-=1 when pressed
	if id > 0:
		id -= 1
		item_update()   
	
func _on_right_pressed():    # > id+=1 when pressed
	if id < 3:
		id += 1
		item_update()

func _on_add_pressed():   #adds the amount from spin_box to the dictionary 
	var add_amount = input_value.value   #spin_box value
	if id == 0 :
		items["fruits"] += add_amount
	elif id == 1:
		items["vegetables"] += add_amount
	elif id == 2:
		items["meat"] += add_amount
	elif id == 3:
		items["fish"] += add_amount
	items_stored_text()

the script works fine but my problem is here

    if id == 0 :
		items["fruits"] += add_amount
	elif id == 1:
		items["vegetables"] += add_amount
	elif id == 2:
		items["meat"] += add_amount
	elif id == 3:
		items["fish"] += add_amount

every time if i want to add the value i have to call like this for each item

items["fruits"] += add_amount

for 3 or 4 items, its ok. if i had 10 or 20 or maybe hundred items then it would be big problem

is there a way to call items by their id without calling like above for every item
for example adding amount to item by their id like this

items[id] += add_amount

if i do this in actual i get error.

:bust_in_silhouette: Reply From: klaas

HI,
you get an error because id is a number and you want a string. The string is in your items_array.

Try this

items[items_array[id]] = += add_amount

Thank you now the script is better!

Mani Vannan | 2020-08-22 06:01

:bust_in_silhouette: Reply From: IHate

If you get the name of the category from your code (the string id) you can look for the string on your array and get its index

#var id = "vegetables"
var array_index = items_array.find(id)  

This will save the index(position in the array) of the string you were looking for. In this case the index will be 1 because the first index starts at 0 and it would be “meat” and now with the index you can do what Klaas said

items[items_array[array_index]] += add_amount

you can put it all in a one liner like this but I wouldn’t recommend it makes it harder to read

 items[items_array[items_array.find(id)]]+= add_amount

But what I would do is to use a 2D Array that’s an array inside an array one stores the the “strings/categories” and the other the “amounts” every category has.
For what I know Godot doesn’t have Build in 2D arrays so you need a function to create one there’s multiple answered questions about how to do it.

Thank you for suggestion I am looking into 2d array, for now I am gonna use klass’s code.

Mani Vannan | 2020-08-22 06:04