Am 29.01.2024 um 00:03 schrieb Sven Schreiber:
Hi,
I needed to check whether a bundle contains a certain gretl object
type, so I put together a fairly general but straightforward function
that counts all the various types.
Comments welcome; in particular whether this should go into the
"extra" addon. Also, do you like the return format or do you have a
better idea?
Below is a variation of the function, which now returns a bundle,
because it now also provides information about the members' names in the
respective object type category.
Comments still welcome, of course.
cheers
sven
----
<hansl>
# new variation
function bundle bundle_member_types (const bundle b)
# Checks the types of the members of b.
# I. counts their occurrences; creates a vector with 12 rows,
holding the
# contained number of members of the possible types in the order
corresponding
# to the inbundle() function:
#
# 1. scalar, 2. series, 3. matrix, 4. string, 5. bundle,
# 6. array, 7. list.
#
# Since an 'array' can be of various sub-types, the rows 8-12
# hold the numbers of those sub-types:
# 8. matrices, 9. bundles, 10. strings, 11. lists, 12. arrays.
#
# Therefore the sum of rows 8-12 equals the number in 6.
#
# This vector is called "counts", as part of the return bundle.
#
# II. records the names (keys) of the bundle, grouped by their type,
# each in an array of strings.
# Example: For the return bundle "out", out.listnames contains a
strings array
# with as many elements as there are list objects in the input b,
each holding
# a list's name.
# Therefore, nelem(out.listnames) is equal to out.counts[7]. In
that sense, "counts"
# would be redundant.
#
# init
strings sinit = array(0)
bundle out = _(counts = zeros(12), scalarnames=sinit,
seriesnames=sinit,
matrixnames=sinit, stringnames=sinit, bundlenames=sinit,
arraynames=sinit,
listnames=sinit,
matricesnames=sinit, bundlesnames=sinit, stringsnames=sinit,
listsnames=sinit,
arraysnames=sinit)
rnameset(out.counts, "scalar series matrix string bundle array list
" ~ \
"matrices bundles strings lists arrays")
# check all the members
if nelem(b)
keys = getkeys(b)
loop foreach i keys
type = inbundle(b, "$i") # should be non-zero by construction
out.counts[type]++
string typn_ = typename(b["$i"])
out.@typn_names += "$i"
if type == 6 # array
if typn_ == "matrices"
out.counts[8]++
elif typn_ == "bundles"
out.counts[9]++
elif typn_ == "strings"
out.counts[10]++
elif typn_ == "lists"
out.counts[11]++
elif typn_ == "arrays"
out.counts[12]++
else
print typn_
funcerr "shouldn't happen"
endif
endif
endloop
endif
# quick cross-check
errorif(out.counts[6] != sum(out.counts[8:12]), "array counts don't
match")
return out
end function
</hansl>