How does one find out whether a field in an object in an array exists? The commented out echo declared(c1.content[0].thing) errors.
How do I find whether a value in a field of an object in an array exists using a proc, or template? The commented out code shows my failure.
type
Box = object
thing: string
food: bool
Container = object
content: seq[Box]
var c1 = Container(
content: @[
Box(thing: "cake", food: true),
Box(thing: "truck", food: false),
Box(thing: "black puddin'", food: true),
Box(thing: "dandelion", food: true)
]
)
echo type c1
echo type c1.content
echo type c1.content[0]
echo type c1.content[0].thing
echo declared(c1.content)
#echo declared(c1.content[0].thing)
var found = 0
let item = false
for obj in items(c1.content):
if obj.food == item:
echo found
inc(found)
#proc findInObjSeq*[T, S, P](a: T, field: P, item: S): int {.inline.} =
# result = 0
# for obj in items(a):
# if obj.field == item: return
# inc(result)
# result = -1
#
#echo findInObjSeq(c1, food, true)
From your example it seems that you want to count quantity of specified items in seq. You can do this easily with sequtils.countIt:
import std/sequtils
echo c1.content.countIt(it.food == true) # 3
If you don't need a count and only want to check if item is present - use sequtils.anyIt:
import std/sequtils
echo c1.content.anyIt(it.food == true) # true
Not entirely sure what exactly you want findInObjSeq to do. Is this supposed to return you a count? An Index? An instance from the list?
Either way, if you want to get past this entirely without macros you will need to make use of the when keyword instead of "if". And also the fieldpairs iterator.
When is like an if-check at compiletime, if you pass the code within the when-block gets compiled into the binary, if not it gets excluded.
proc findInObjSeq*[T, S](objects: openArray[T], fieldName: static string, value: S): int =
## Returns index of first occurrence of an object in `objects` that has a field named `fieldName` with the value `value`.
## Returns -1 if no object in objects has a field named `fieldName`.
## Returns also -1 if the objects in `objects` contain a field with that name, but no value equaling `value`
for index, obj in objects:
for objFieldName, fieldValue in obj.fieldPairs:
when objFieldName == fieldName:
if fieldValue == value:
return index
return -1
What this does is:
Thank you both. Enough to fiddle with. The goal is to find the index of the first occurrence of Box(food: value), if at all. Like seq.find(value)
Cheers.