0

i need multidimensional arrays in bash, i wrote myself a function, but it is too slow,
is there a library outthere for faster array access.

For creating 1000 entries of childarrays in the parent array and then reading out the child array's first element, all through,
i need 0.157s

time { for ((i=0;i<1000;i++)); do arrOFarr test create $i "ab ab ab ab ab ab ab ab ab ab ab ab ab"; done; for index in ${!test_arrOFarr[*]}; do arrOFarr test get $index; echo $arrOFarr_item; done }

i have this function:

#!/bin/bash

#-- call:        arrOFarr [array basename STR] [action STR] [index INT] [action additional argument STR or bINT] 
#-- description: allows arrays of arrays as items. the parent array is an indexed array, the child array can be an associative or indexed array.
#-- parameters:  $1 ... array basename STR - the basename of the parent array, the array is set in the shell parameters with "_arrOFarr" addition to the basename
#                                            created items (child arrays) of the parent array are set with "_arrOFarr_item_"(unique number) addition
#--              $2 ... action STR - the type of action
#--                                     In the following examples test is the basename of the parent array and so it is set in shell parameters as "test_arrOFarr"
#--                                     create  ... creates an indexed array, with the item string, overhanded as action argument
#--                                                 and adds it to the parent array at index position. If the parent array doesnt exists yet, it will be created!
#--
#--                                                     arrOFarr test create 0 "hello bello cello dello"                             unquoted items
#--                                                     arrOFarr test create 1 '"hello" "bello" "*" "?"'                             quoted items - prohibit file globbing
#--                                                     $varname="hello_bello_cello"; IFS="_" arrOFarr test create 2 '$varname'      items by word splitting
#--
#--                                                 the indexed array are set in the shell parameters as "test_arrOFarr_item_"(unique number)
#--                                                 Attention: if word splitting is used, use set -o noglob to prohibit that data characters * ? [] are recognized as file patterns,
#--                                                            if these characters are in the action argument.
#--
#--                                     add     ... adds an already existing associative or indexed array to the parent array at index position, the variable name is overhanded in the action argument
#-- 
#--                                                     x=(ab bb bc); arrOFarr test add 3 x
#--                                      
#--                                     get     ... gets the items of the parent array at index position, the child_array is finally linked under shell parameter "arrOFarr_item" !!!!
#--                                                     arrOFarr test get 0  -- gets the item with index 0
#--                                                
#--                                     unset   ... unsets the item of the parent array at index position and unsets the linked child array in the shell parameters
#--                                                 or if index "-" unsets the complete arrOFarr parent array and its child arrays in the shell parameters
#--                                                     arrOFarr test unset 0   -- unsets an item of the parent array
#--                                                     arrOFarr test unset -   -- kills complete arrOFarr parent array
#--
#--                                     rewrite ... rewrites the parent array, removing empty places in the array
#--                                                     arrOFarr rewrite
#--                                                 
#--              $3 ... index INT - the array index of the parent array for the action
#--
#--              $4 ... action argument
#--                     create  - STR  ... the item string of the created indexed array - "hello bello cello dello" - examples see create
#--                     add     - STR  ... the variable name of the associative or indexed array to add
#--                     get     - not needed
#--                     unset   - not needed
#--                     rewrite - not needed  
#-- depends on: -
arrOFarr ()
    {
    #-- example array basename is test
    local arrOFarr_varname="${1}_arrOFarr"
    local -n arrOFarr_isSet="${arrOFarr_varname}_isSet"
    
    #-- check if arrOFarr is set, if not set it
    if ((${#arrOFarr_isSet}==0)); then
        declare -ga "${arrOFarr_varname}=()"                                                  #--added as test_arrOFarr to shell parameters
        declare -g "${arrOFarr_varname}_unique_counter=0" "${arrOFarr_varname}_isSet=true"    #--added as test_arrOFarr_unique_counter, test_arrOFarr_isSet to shell parameters
    fi

    local -n arrOFarr=$arrOFarr_varname arrOFarr_unique_counter="${arrOFarr_varname}_unique_counter"   #-- link the variables, arrOFarr ... parent array, arrOFarr_unique_counter ... as unique id for the name of child arrays
    local arrOFarr_childarray_basename="${arrOFarr_varname}_item_"                                     #-- becomes test_arrOFarr_item_
    
    case $2 in
        "create")
            arrOFarr_varname=$arrOFarr_childarray_basename$arrOFarr_unique_counter                     #-- arrOFarr varname redefined to child array varname, 
            declare -ga "$arrOFarr_varname=($4)"                                                       #-- child array added as test_arrOFarr_item_(uniqueID) to shell parameters
            arrOFarr[$3]=$arrOFarr_varname                                                             #-- the child array variabel name is set as item in the parent array
            ((arrOFarr_unique_counter++));;
        "add")
            arrOFarr[$3]=$4;;                                                                          #-- adds an existing associative or indexed array to the parent array
        "get")
            declare -gn arrOFarr_item=${arrOFarr[$3]};;                                                #-- links the child array to shell parameter arrOFarr_item
        "unset")
            if [[ $3 == "-" ]]; then
               unset "${arrOFarr[@]}" arrOFarr arrOFarr_unique_counter arrOFarr_isSet                  #-- unsets the complete parent array
            else
               unset ${arrOFarr[$3]} arrOFarr[$3]                                                     #-- unsets the child array in the shell parameters and unsets the name of the child array in the parent array
            fi;;
         "rewrite")
            arrOFarr=("${arrOFarr[@]}");;                                                              #-- rewrites the array killing empty indices
    esac
    }
14
  • 9
    If you need multidimensional arrays, bash and other shells are the wrong choice.
    – Shawn
    Dec 20, 2023 at 3:33
  • 1
    bash is mostly an unfinished clone of ksh. ksh93 does have multi-dimensional arrays and since bash syntax is mostly a subset of that of ksh93', switching to that shell shouldn't be too painful. But I'd agree switching to a proper programming languages would make a lot more sense. Dec 20, 2023 at 10:22
  • 1
    "i need multidimensional arrays in bash" No! Bad human, no!
    – pipe
    Dec 20, 2023 at 11:07
  • 1
    Your function/example doesn't work for me and I don't really understand how you want your array to look
    – jesse_b
    Dec 20, 2023 at 12:17
  • 2
    Thanks for sharing. I don't see a question in your question. Did you want codereview.stackexchange.com ? ... Oh, there it is: "is there a library outthere for faster array access" -- No is the answer. Dec 20, 2023 at 13:56

0

You must log in to answer this question.

Browse other questions tagged .