我需要在数组中找到最常用的数字。我是这样做的:
# our array, the most frequent value is 55
declare -a array=(44 55 55 55 66 66)
# counting unque string with uniq and then sorting as numbers
array=($(printf "%s\n" "${array[@]}"| uniq -c | sort -n -r))
# printing 2nd element of array, as the first one - number of occurencies
printf ${array[1]}
这是一种更好/更美丽的方式吗,而不是构建一个奇怪的数组(第二步),其中包含混合计数和数字?
我是否正确排序? (uniq
返回2列中的值,因此我不确定它是如何选择列的)
答案 0 :(得分:4)
如果我必须在bash
中执行此操作,我会使用awk
来跳过对任何内容的排序,并只计算元素:
printf '%s\n' "${array[@]}" | awk '{
if (++arr[$0] > max) {
max=arr[$0];
ans=$0
}
}
END {print ans}'
您还可以使用关联数组在bash
4或更高版本中实现相同的算法:
# These don't strictly need to be initialized, but it's safer
# to ensure they don't already have values.
declare -A counts=()
max=0
ans=
for i in "${array[@]}"; do
if ((++counts[$i] > max)); then
max=${counts[$i]}
ans=$i
fi
done
printf '%s\n' "$ans"
答案 1 :(得分:2)
在#!/usr/bin/env bash
declare -a array=(44 55 55 55 66 66)
declare -A hashMap
declare -i max=0
for element in "${array[@]}"; do
((hashMap["$element"]++))
done
for key in "${!hashMap[@]}"; do
(( "${hashMap[$key]}" > max )) && { max="${hashMap[$key]}"; element="$key" ; }
done
printf '%d\n' "$element"
v4 +向前使用关联数组的更简洁的chepner逻辑版本。我们使用key作为数组元素构建关联数组SELECT *
FROM "db1"."tbl1"
WHERE year = cast(extract(year from (CURRENT_DATE - interval '7' day)) as varchar)
AND month = lpad(cast(extract(month from (CURRENT_DATE - interval '7' day)) as varchar),2,'0')
AND day = lpad(cast(extract(day from (CURRENT_DATE - interval '7' day)) as varchar),2,'0')
limit 10
,并将其出现的计数作为值。构建数组后,我们从具有最大计数的数组中找到并检索其值。
{{1}}
答案 2 :(得分:1)
如果您不想使用 awk 执行此操作,您仍然可以使用排序和 uniq 进行此操作但请注意,您需要在计数之前将输入 ALREADY 排序。否则它将无法工作。例如:
declare -a array=(34 3 45 45 66 55 44 55 55 55 66 45 45 8 6 45 45 66 32 9 18)
printf "%s\n" "${array[@]}" | sort -n -r | uniq -c | sort -n -r | head -1 | awk '{print $2}'
对于给定的输入,代码正确地提取最重复的数字,但是在你给它的样本中它将不起作用并且它将告诉55是最重复的数字,虽然这是错误的,因为它显然是45,但是 uniq 仅计算连续项目,如果它们稀疏则会错误地计算它们。
Regads!
答案 3 :(得分:1)
另一个极简主义者awk
$ awk '{for(mi=i=1;i<=NF;i++) if(a[$mi]<++a[$i]) mi=i; print $mi}' <<< "${array[@]}"