Best way to simulate multidimensional arrays "objects" in BASH?

Progress 15: The first step toward the elegant answer

Re-beating the 1st challenge in pure BASH

MY_DATA=`cat << 'EOF'
	SpaceX
		headquarters
			address:Rocket Road
			city:Hawthorne
			state:California
		links
			website:https://www.spacex.com/
			flickr:https://www.flickr.com/photos/spacex/
			twitter:https://twitter.com/SpaceX
			elon_twitter:https://twitter.com/elonmusk
		name:SpaceX
		founder:Elon Musk
		founded:2002
		employees:8000
EOF`

Posted here (and below) was an answer to a self-challenge that I set that I could a read multi-dimensional associate arrays in BASH in < 10 lines.

Sadly that was “BASH” in big air quotes because it was really a RegEx string generator for grep to find the result using PCRE (why I later renamed it BAAMX) and if the BAAML had newlines they had to be removed.

# If the database has newlines, old BAAM needs them removed:
MY_DATA=${MY_DATA//$'\n'/}
BAAM (){ # BAAM - [B]ASH [A]ssociative [A]rrarys in [M]ulti-dimensions
	REGEX_STR='(^|[^\t])\t{1}'$2'((?=\t{2}[^\t])|:)\K.*?'
	LEVEL=1
	for PROP_NAME in "${@:3}"; do
		REGEX_STR+='\t{'$((LEVEL++))'}'$PROP_NAME'((?=\t{'$(($LEVEL+1))'}[^\t])|:)\K.*?'
	done
	REGEX_STR+='[^\t](?=$|\t{1,'$LEVEL'}[^\t])'
	echo $(echo "$1" | grep -oPe "$REGEX_STR")
}

Here’s the solution in 9 lines of pure BASH 10 months later.

BAAM (){ # BAAM - [B]ASH [A]ssociative [A]rrarys in [M]ulti-dimensions
	DbLayer=$1; shift; Blocks=
	for Prop in "$@"; do
		Blocks=$Blocks'	'
		DbLayerNext=${DbLayer#*$Blocks$Prop[^[:alnum:]]}
		DbLayer=${DbLayerNext%%$'\n'$Blocks[^	]*}
	done
	printf '%s' "$DbLayer"
}

Both give the same result:

echo "$(BAAM "$MY_DATA" SpaceX links website)"

https://www.spacex.com/

But will it run Crysis?

No.

This speed test grabs the website of SpaceX from the dataset and puts it in a variable 50,000 times.

for value in {1..50000}; do
	Val=$(BAAM "$MY_DATA" SpaceX links website)
done

Results

Old version using PCRE:
(I removed the new lines before the loop to make things as fast as possible)

Run 1: 2m39.959s
Run 2: 2m40.426s
Run 3: 2m40.119s

New version using pure BASH:

Run 1: 41.188s
Run 2: 39.975s
Run 3: 39.628s

Conclusions

Same number of lines, less code and 5x faster at 1,250 lookups per second.

I tried exchanging the last line of the old version for the Perl solution but it increased times to 3m26s.

perl -e "'$1' =~ m/$REGEX_STR/s; print $&;"

This project is now firmly on the road to an elegant pure BASH solution.