To jest mój kod:

function get_index() {
 my_array="$1"
 value="$2"
 for i in "${!my_array[@]}"; do
   if [[ "${my_array[$i]}" = "${value}" ]]; then
       echo "was found"
       echo "${i}";
   fi
 done
 return -1
}

echo "index test"
get_index "${cut_pages[@]}" 5
index=$?
echo $index

Tablica zawiera 2 i 5 Musi zwrócić 1, ale zwraca 255

Jaki jest problem?

0
Ahmad 2 kwiecień 2020, 19:14

3 odpowiedzi

Najlepsza odpowiedź

Możesz użyć odwołania do tablicy zamiast przekazywania całej tablicy jako pojedynczych argumentów:

function get_index() {
  local -n my_array=$1 # use -n for a reference to the array
  for i in "${!my_array[@]}"; do
    if [[ ${my_array[i]} = $2 ]]; then
      printf '%s\n' "$i"
      return
    fi
  done
  return 1
}

cut_pages=( 1 2 3 4 5 )
index=$(get_index cut_pages 5) && echo "index=$index"
2
Freddy 2 kwiecień 2020, 16:45

Nie możesz przekazać tablicy jako pojedynczego argumentu do funkcji. Kiedy piszesz "${cut_pages[@]}", rozkłada tablicę na oddzielne argumenty funkcji.

Zmieniłem funkcję tak, aby jako pierwszy argument przyjmowała wartość do wyszukania, a tablica zawiera wszystkie pozostałe argumenty. Po przypisaniu tego do value, polecenie shift usuwa je z listy argumentów, a następnie wykonuję iterację po "$@", aby przetworzyć pozostałe argumenty.

Nie otrzymujesz również wyniku funkcji poprawnie. $? zawiera kod stanu w instrukcji return. Aby uzyskać to, co powtarza funkcja, użyj $(...). Usunąłem echo "was found", więc to nie wpłynie na wynik.

#!/bin/bash

function get_index() {
    value="$1"
    shift
    local index=0
    for i in "$@"; do
        if [[ "$i" = "${value}" ]]; then
            echo "${index}";
            return
        fi
        ((index++))
    done
    return 1
}

echo "index test"
cut_pages=(2 5)
if index=$(get_index 5 "${cut_pages[@]}"); then
    echo $index
fi
2
Barmar 2 kwiecień 2020, 16:28

Rozwijając inne odpowiedzi, tutaj przedstawiono funkcje obsługujące wartości w wielu indeksach; i do obsługi wielokrotności wartości w wielu indeksach, z zwracaniem wyniku do tablicy:

#!/usr/bin/env bash

function get_indexes() {
  local -n my_array="$1" # use -n for a reference to the array
  local -a indx=()
  local -i rc=1
  for i in "${!my_array[@]}"; do
    if [ "${my_array[i]}" = "$2" ]; then
      indx+=("$i")
      rc=0
    fi
  done
  echo "${indx[*]}"
  return $rc
}

function get_all_indexes() {
  if [ $# -lt 3 ]; then
    printf 'get_all_indexes input_array output_array values...\n' >&2
    return 2
  fi
  local -n input_array="$1" # use -n for a reference to the array
  shift
  local -n output_array="$1"
  shift
  if ! [[ "$(typeset -p "${!output_array}")" =~ ^declare\ -A ]]; then
     printf 'Output array %s must be an associative array!\n' "${!output_array}" >&2
     return 2
  fi

  local -i rc=1
  for i in "${!input_array[@]}"; do
    for value; do
      if [ "${input_array[$i]}" = "$value" ]; then
        if [ ${#output_array[$value]} -eq 0 ]; then
          output_array[$value]="$i"
        else
          printf -v output_array[$value] $'%s\3%s' "${output_array[$value]}" "$i"
        fi
        rc=0
      fi
    done
  done
  return $rc
}

echo "Testing multi indexes single value"
declare -a cut_pages=([3]=2 [7]=5 [1]=3 [0]=5)
typeset -p cut_pages
if indexes=$(get_indexes cut_pages 5); then
  echo "found 5 at indexes:"
  echo "$indexes"
fi

printf "\n\nTesting multi indexes multiple values output to array\n"
declare -A out_arr=()
declare -A in_arr=(
 ["first"]="hello"
 ["second"]="world"
 ["third"]="hello"
 ["fourth"]="you"
)
typeset -p in_arr

if get_all_indexes in_arr out_arr "hello" "world" "you"; then
  for k in "${!out_arr[@]}"; do
    printf 'Found %q at indexes:\n' "$k"
    IFS=$'\3' read -r -a indexes <<<"${out_arr[$k]}"
    printf '%q\n' "${indexes[@]}"
  done
fi

Wynik wyjściowy:

Testing multi indexes single value
declare -a cut_pages=([0]="5" [1]="3" [3]="2" [7]="5")
found 5 at indexes:
0 7


Testing multi indexes multiple values output to array
declare -A in_arr=([fourth]="you" [third]="hello" [first]="hello" [second]="world" )

Found world at indexes:
second
Found you at indexes:
fourth
Found hello at indexes:
third
first
2
Léa Gris 2 kwiecień 2020, 18:21