aca301f64c1466e8b7b0810d898b62c6e06dc246
[feisty_meow.git] / scripts / core / array_sifter.sh
1 #!/bin/bash
2 #
3 # Provides functions for checking and sorting the contents of arrays.
4
5
6 #hmmm: these could all be beefed up by properly handling spaces in array
7 #      entries.  use "${blah[@]}" rather than '*' for getting all elems.
8
9
10 # given the name of an array as the first parameter, this signals
11 # success (return value zero) if the second parameter is found in the
12 # array.  failure (non-zero return) occurs if the item is missing.
13 function test_presence()
14 {
15   array_name=$1; shift
16   flag_to_find=$1; shift
17   temp_name="${array_name}[*]"
18   declare -a array_to_check=(${!temp_name})
19 #echo "array to check is: ${array_to_check[*]}"
20   local i;
21   for (( i=0; i < ${#array_to_check[*]}; i++ )); do
22     if [ "${array_to_check[i]}" == "$flag_to_find" ]; then
23 #      echo "found the flag $flag_to_find"
24       return 0
25     fi
26   done
27 #  echo "did not find the flag $flag_to_find"
28   return 1
29 }
30
31 # takes two arrays of items and checks whether any of the members of the second
32 # array are present in the first array.  zero is returned when a match is found.
33 function match_any()
34 {
35   match_within_name=$1; shift
36   items_to_match_name=$1; shift
37 #  temp_name="${match_within}[*]"
38 #  declare -a match_within_array=(${!temp_name})
39 #echo "the list to match within is: ${match_within_array[*]}"
40   temp_name="${items_to_match_name}[*]"
41   declare -a items_to_match_array=(${!temp_name})
42 #echo "the items to match are: ${items_to_match_array[*]}"
43
44   for onetag in ${items_to_match_array[*]}; do
45 #echo curr tag is $onetag 
46     test_presence $match_within_name $onetag
47     if [ $? -eq 0 ]; then return 0; fi  # got a match.
48   done
49   return 1  # no match found.
50 }
51
52 # sifts an array by finding matching items in a second array and storing
53 # those extracted items into a third array.  the original array is modified
54 # by removing those matched items.  the first parameter is the array to sift,
55 # the second is a list of items to sift out of the array, and the third is
56 # an array to fill with removed/matched items.  each of these is just a
57 # name, which will be indirectly referenced to get its contents.
58 # success (zero) is returned when any item to match was found in the array.
59 function sift_array()
60 {
61   sift_name=$1; shift
62   temp_name="${sift_name}[*]"
63   declare -a array_to_sift=(${!temp_name})
64   match_name=$1; shift
65   temp_name="${match_name}[*]"
66   declare -a match_items=(${!temp_name})
67   store_name=$1; shift
68
69   declare -a temp_store=()  # put our extracted items for the moment.
70
71   # seek backwards through the array to sift, so we can destructively
72   # rearrange it without adjusting loop index.
73   sift_len=${#array_to_sift[*]}
74   local i; local j;
75   for (( i=$sift_len; i >= 0; i-- )); do
76     # look through match items to see if they're in the sifting array.
77     for (( j=0; j < ${#match_items[*]}; j++ )); do
78       curname=${match_items[$j]}
79       if [ "${array_to_sift[$i]}" == "$curname" ]; then
80         # found a lucky participant; move it to the storage array.
81         temp_store+=($curname)
82 #echo temp store now ${temp_store[*]}
83         # remove this item from the containing array.
84         ((after=$i+1))
85         ((afterlen=$sift_len-$i))
86
87         array_to_sift=(${array_to_sift[*]:0:$i} ${array_to_sift[*]:$after:$afterlen})
88       fi
89     done
90   done
91
92   # update our list for what was removed.
93   eval ${sift_name}=\(${array_to_sift[*]}\)
94
95   # now assign to the external arrays.
96   eval ${store_name}=\(${temp_store[*]}\)
97
98   if [ ${#temp_store} -ne 0 ]; then
99     return 0
100   else
101     return 1
102   fi
103 }
104