How to treat seq as return value in Nim

I am facing a problem with Nim sequences and returning them from a function.

json_p.nim(42, 33) template/generic instantiation from here
json_p.nim(28, 22) Error: no generic parameters allowed for seq

      

Line 28 is where I define mine key_list

proc get_json_keys(json_data: JsonNode) : seq =
    var key_list: seq[string] = @[] # 28
    var key: string
    for record in json_data:
        for key, value in record:
            if (not key_list.contains(key)):
                key_list.add(key)
    return key_list

      

I'll just name it from the main one.

proc main() : void =     
    var file = get_url()
    var json_data = file.parseFile()

    [...]

    var key_list = get_json_keys(json_data)
    for key in key_list:
        echo key

      

The code works fine inside the main function.

+3


source to share


1 answer


Problems:

* seq is a generic dynamic array and you can only add a key and the whole search will be linear as it is similar to a C language array.

* All return values โ€‹โ€‹of functions have a default "result" with a variable name. You must use it to return your values.

* Using ".contains" will cause nim to search the entire array to check. The best option is to use a fast search container.

I assume you need:

* function to process json duplicate keys and return a unique list with fast key lookup.

Implementation:

import json,tables

proc get_json_keys(json : JsonNode):OrderedTable[string,string]=
  #initialize the result object
  result = initOrderedTable[string,string]()
  #more info,see https://nim-lang.org/docs/json.html
  for key,value in json.pairs():
    #debugging...
    #echo key & "-" & value.getStr()
    if not result.contains(key):
      result[key]=value.getStr()

var json_data = parseJson("""{"key1" :"value1","key2" :"value2" }""")
var key_list = get_json_keys(json_data)
for key in key_list.pairs() :
  echo key

      

Output:



(Field 0: "key1", field1: "value1")

(Field 0: "key2", field1: "value2")


If search speed is not an issue, you can also do this:

Implementation using seq:

proc get_json_keys(json : JsonNode):seq[string]=
  result = newSeq[string](0)
  for key,value in json.pairs():
    if not result.contains(key):
      result.add(key)

var json_data = parseJson("""{"key1" :"value1","key2" :"value2","key1":"value3" }""")
var key_list = get_json_keys(json_data)
echo key_list

      

Output:



@ ["key1", "key2"]

obs: edited my answer because seq is not immutable if declared with 'var'. It is only immutable if "let" is declared.

+1


source







All Articles