【问题标题】:Bash: Count total number of keys in an associative array?Bash:计算关联数组中的键总数?
【发布时间】:2020-12-11 10:24:09
【问题描述】:

考虑下面的关联数组:

declare -A shapingTimes
 shapingTimes=([0-start]=15 [0-stop]=21 [0-anotherkey]=foo)
shapingTimes+=([1-start]=4  [1-stop]=6  [1-anotherkey]=bar)
shapingTimes+=([2-start]=9  [2-stop]=11 [2-anotherkey]=blah)

有没有办法找到数组中每个条目使用的键总数? (这是数组中的每个“索引”吗?)

例如,如何计算:[start]、[stop]、[anotherkey] as = 3 个键?

目前我正在使用我发现(如下所示)的代码中的硬编码值 (3),它可以很好地完成工作,但我想知道这是否可以动态实现?

totalshapingTimes=$((${#shapingTimes[*]} / 3))

我发现这些变量返回各种数组方面,但不返回键的总数

echo "All of the items in the array:" ${shapingTimes[*]}
echo "All of the indexes in the array:" ${!shapingTimes[*]}
echo "Total number of items in the array:" ${#shapingTimes[*]}
echo "Total number of KEYS in each array entry:" #???

期望的输出:

All of the items in the array: 21 6 11 blah 15 4 bar 9 foo
All of the indexes in the array: 0-stop 1-stop 2-stop 2-anotherkey 0-start 1-start 1-anotherkey 2-start 0-anotherkey
Total number of items in the array: 9
Total number of KEYS in each array entry: 3

【问题讨论】:

    标签: arrays bash associative-array


    【解决方案1】:

    @Cyrus's solution 相同,但没有循环和子shell:

    #!/usr/bin/env bash
    
    declare -A shapingTimes=(
      [0-start]=15 [0-stop]=21 [0-anotherkey]=foo
      [1-start]=4  [1-stop]=6  [1-anotherkey]=bar
      [2-start]=9  [2-stop]=11 [2-anotherkey]=blah
    )
    
    # Populate simple array with keys only
    declare -a shapingTimesKeys=("${!shapingTimes[@]}")
    
    # Create associative array entries declaration string
    # populated by prefix stripped keys
    printf -v _str '[%q]= ' "${shapingTimesKeys[@]/#[0-9]*-/}"
    
    # Declare the stripped keys associative array using
    # the string populated just above
    declare -A shapingTimesHash="($_str)"
    
    printf 'Found %d keys:\n' "${#shapingTimesHash[@]}"
    printf '%q\n' "${!shapingTimesHash[@]}"
    

    【讨论】:

      【解决方案2】:
      declare -A shapingTimes
      shapingTimes=([0-start]=15 [0-stop]=21 [0-anotherkey]=foo)
      shapingTimes+=([1-start]=4  [1-stop]=6  [1-anotherkey]=bar)
      shapingTimes+=([2-start]=9  [2-stop]=11 [2-anotherkey]=blah)
      
      # output all keys
      for i in "${!shapingTimes[@]}"; do echo $i; done
      

      输出:

      1-启动 2站 1 站 0-开始 2开始 2-另一个键 1-另一个键 0-停止 0-另一个键
      # Leading numbers and "-" removed:
      for i in "${!shapingTimes[@]}"; do echo ${i/#[0-9]*-/}; done
      

      输出:

      开始 停止 停止 开始 开始 另一个键 另一个键 停止 另一个键
      # put shortend keys in new associative array
      declare -A hash
      for i in "${!shapingTimes[@]}"; do hash[${i/#[0-9]*-/}]=""; done
      echo "${#hash[@]}"
      

      输出:

      3

      【讨论】:

      【解决方案3】:

      使用- 键入数组名称后,就没有直接的方法来确定字符串在- 字符之后出现的次数。

      一种方法是使用其他工具来识别计数。 "${!shapingTimes[@]}" 打印数组的所有键,sort -ut- k2 基于 - 分隔符后的 2nd 字段进行唯一排序,该分隔符通过管道传送到 wc -l 以获取该行数。

      printf '%s\n' "${!shapingTimes[@]}" | sort -ut- -k2 | wc -l
      3
      

      【讨论】:

        猜你喜欢
        • 2021-03-23
        • 1970-01-01
        • 2013-10-10
        • 1970-01-01
        • 1970-01-01
        • 2019-05-03
        • 2019-07-06
        • 1970-01-01
        • 2019-08-22
        相关资源
        最近更新 更多