【问题标题】:Getting length of part of associative array (double) in Bash在 Bash 中获取部分关联数组(双精度)的长度
【发布时间】:2018-01-16 00:05:01
【问题描述】:

我有一个关联数组,其行为类似于通常的双数组。

结构类似于:[ [0,1], [0,1,2] ]。代码:

declare -A array
array[0,0]=0
array[0,1]=1
array[1,0]=0
array[1,1]=1
array[1,2]=2

我如何获得 array[0]array[1] 的长度?在本例中:2 和 3。

谢谢。

附:我试图搜索重复项。没有成功。如果不清楚:我不知道数组的长度。


答案是在效率测试后选择的。这是基于@RenaudPacalet 回答的函数示例:

function getLength() {
    local k=$(eval "echo \${!$1[@]}")
    local re="(\<$2,[0-9])"
    echo $k | grep -Eo $re | wc -l
}

用法示例:getLength array 1 在本题中返回 3。

请记住,使用 $(eval "echo \${!$1[@]}") 比使用 ${!array[@]} 慢得多。

【问题讨论】:

  • "这就像它通常的双数组" 不,它没有,它总是充当关联数组。
  • 回声 ${#array[@]}
  • @Ignacio Vazquez-Abrams,我的意思是它让人想起双数组。不行动,如果你愿意:)
  • @py9,这有什么帮助?
  • bash 不支持多维数组(array[0,0] 只是索引为“0,0”的列表元素)。见stackoverflow.com/questions/12317483/array-of-arrays-in-bash

标签: arrays bash unix multidimensional-array bash4


【解决方案1】:
k=${!array[@]}
n=0
re="(\<$n,[0-9]+)"
echo $k | grep -Eo $re | wc -l
  1. 获取数组的键,
  2. 设置行索引,
  3. 为匹配的键创建正则表达式,
  4. 使用正则表达式过滤键并计算匹配数。

如果需要,还可以重复使用其他行索引。正则表达式有点棘手。 \&lt; 是单词的开头(以避免10,10 匹配0,)。 $n,[0-9]+ 是当前行索引,后跟一个逗号和一个或多个数字。括起来的括号分隔子表达式。

grep 的-Eo 选项将其置于扩展正则表达式模式,并将匹配的字符串用新行分隔,以便wc -l 可以计算它们。

【讨论】:

  • 它只能在 RegEx 中不带 * 的情况下工作。 grep 的 2.5.1 版本。
  • 这个实现真的很不幸。考虑一下你是否有一个文字星号作为键——echo * 将发出一个文件名列表。而grep -o 是 GNUism,the POSIX spec for grep 不保证。
  • @CharlesDuffy 以问题为例,这没关系。但我明白你的意思。欣赏这两个答案。这就是为什么我通过指定选择答案的标准来更新问题。
  • @MOPO3OB,效率因测试场景而异——这在大型阵列上会更快,在小型阵列上会更快(因为启动管道、外部 grep 命令等. 有一个非常重要的恒定成本)。如果您要展示这个答案是使用小数组大小获得更高性能,我非常想查看您的测试过程。
  • @CharlesDuffy 同意了。两个答案的小数据效率几乎相同。可以感受到超过 10k 个元素的数组的差异。
【解决方案2】:

您必须遍历数组键并计算您关心的键:没有像 ${array[0,*]) 这样的语法

n0=0
n1=0
for key in "${!array[@]}"; do 
    [[ $key == 0,* ]] && ((n0++))
    [[ $key == 1,* ]] && ((n1++))
done
echo $n0
echo $n1

或者,使用数组来计算所有“第一级”索引

n=()
for key in "${!array[@]}"; do (( n[${key%%,*}]++ )); done
# then, print out the counts
for ind in "${!n[@]}"; do printf "%s\t%s\n" $ind "${n[$ind]}"; done

【讨论】:

    猜你喜欢
    • 2015-10-02
    • 1970-01-01
    • 2016-04-23
    • 2017-01-06
    • 1970-01-01
    • 2018-08-23
    • 1970-01-01
    • 2013-06-20
    • 1970-01-01
    相关资源
    最近更新 更多