Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
123 changes: 93 additions & 30 deletions ar.bash
Original file line number Diff line number Diff line change
Expand Up @@ -312,20 +312,38 @@ ar::set() {
arr_set=("${!assoc[@]}")
}


## @fn ar::set_in()
## @fn ar::in_set()
## @brief Set membership
## @param arr The array to search
## @param _in_set_arr The array to search
## @param needle The value to search for
ar::in_set() {
local -n arr="$1"
local -n _in_set_arr="$1"
local -A assoc
for val in "${arr[@]}"; do
for val in "${_in_set_arr[@]}"; do
assoc[$val]=1
done
[[ -v assoc["$2"] ]]
}

## @fn ar::set_equal()
## @brief Set equality
## @param _set_equal_arr1 The first set
## @param _set_equal_arr2 The second set
## @retval 0 if sets are equal, 1 otherwise
ar::set_equal() {
local -n _set_equal_arr1="$1"
local -n _set_equal_arr2="$2"
if [[ ${#_set_equal_arr2[@]} != ${#_set_equal_arr1[@]} ]]; then
return 1
fi
for val in "${_set_equal_arr1[@]}"; do
if ! ar::in_set _set_equal_arr2 "$val"; then
return 1
fi
done
return 0
}


## @fn ar::union()
## @brief The union of two sets
Expand All @@ -350,31 +368,6 @@ ar::union() {
union_set=("${!union_assoc[@]}")
}


## @fn ar::print_union()
## @brief Print the union of two arrays
## @detail Can be captured as an array with res=($(punion arr1 arr2))
## @param arr1 The first array
## @param arr2 The second array
ar::print_union() {
local -n arr1="$1"
local -n arr2="$2"
local -A union_assoc
local -a union_set

for val in "${arr1[@]}"; do
union_assoc[$val]=1
done

for val in "${arr2[@]}"; do
union_assoc[$val]=1
done

union_set=("${!union_assoc[@]}")
echo "${union_set[@]}"
}


## @fn ar::intersection
## @brief The intersection of two arrays
## @detail
Expand Down Expand Up @@ -456,6 +449,76 @@ ar::symmetric_difference() {
symmetric_diff_arr=("${!symmetric_diff_assoc[@]}")
}

## @fn ar::is_subset
## @brief Return true if arr1 is a subset of arr2
## @param arr1 The first array name
## @param arr2 The second array name
## @retval 0 if arr1 is a subset of arr2, non-zero otherwise
ar::is_subset() {
local -n arr1="$1"
local -n arr2="$2"
for i in "${arr1[@]}"; do
if ! ar::in_set arr2 "$i"; then
return 1
fi
done
return 0
}

## @fn ar::is_superset
## @brief Return true if arr1 is a superset of arr2
## @param arr1 The first array name
## @param arr2 The second array name
## @retval 0 if arr1 is a superset of arr2, non-zero otherwise
ar::is_superset() {
local -n arr1="$1"
local -n arr2="$2"
for i in "${arr2[@]}"; do
if ! ar::in_set arr1 "$i"; then
return 1
fi
done
return 0
}

## @fn ar::is_proper_subset
## @brief Return true if arr1 is a proper subset of arr2
## @param arr1 The first array name
## @param _arr2 The second array name
## @retval 0 if arr1 is a proper subset of arr2, non-zero otherwise
ar::is_proper_subset() {
local -n _proper_subset_arr1="$1"
local -n _proper_subset_arr2="$2"
if ar::set_equal _proper_subset_arr1 _proper_subset_arr2; then
return 1
fi
for i in "${_proper_subset_arr1[@]}"; do
if ! ar::in_set _proper_subset_arr2 "$i"; then
return 1
fi
done
return 0
}

## @fn ar::is_proper_superset
## @brief Return true if _proper_superset_arr1 is a superset of _proper_superset_arr2
## @param _proper_superset_arr1 The first array name
## @param _proper_superset_arr2 The second array name
## @retval 0 if _proper_superset_arr1 is a superset of _proper_superset_arr2, non-zero otherwise
ar::is_proper_superset() {
local -n _proper_superset_arr1="$1"
local -n _proper_superset_arr2="$2"
if ar::set_equal _proper_superset_arr1 _proper_superset_arr2; then
return 1
fi
for i in "${_proper_superset_arr2[@]}"; do
if ! ar::in_set _proper_superset_arr1 "$i"; then
return 1
fi
done
return 0
}

## @fn array_to_string
## @brief Turn an array into a string with seperator
## @param vname_of_array The variable name of the array
Expand Down
75 changes: 75 additions & 0 deletions tests/test_ar.bats
Original file line number Diff line number Diff line change
Expand Up @@ -158,3 +158,78 @@ setup() {
ar::in_set diff_arr "${expected_diff[i]}"
done
}

@test "ar::is_subset returns 0 if set1 is a subset of set2" {
local -a first_arr=(rice beans sausage)
local -a second_arr=(beans sausage)
run ar::is_subset second_arr first_arr
assert_success
}

@test "ar::is_subset returns non-zero if set1 is not a subset of set2" {
local -a first_arr=(rice beans sausage)
local -a second_arr=(beans sausage pasta)
run ar::is_subset second_arr first_arr
assert_failure
}

@test "ar::is_superset returns 0 if set1 is a superset of set2" {
local -a first_arr=(rice beans sausage)
local -a second_arr=(beans sausage)
run ar::is_superset first_arr second_arr
assert_success
}

@test "ar::is_superset returns non-zero if set1 is not a superset of set2" {
local -a first_arr=(rice beans sausage)
local -a second_arr=(beans sausage pasta)
run ar::is_superset first_arr second_arr
assert_failure
}

@test "ar::set_equal returns 0 if sets are equal" {
local -a first_arr=(rice beans sausage)
local -a second_arr=(rice beans sausage)
run ar::set_equal first_arr second_arr
assert_success

# Order shouldn't matter
local -a first_arr=(rice beans sausage)
local -a second_arr=(beans rice sausage)
run ar::set_equal first_arr second_arr
assert_success
}

@test "ar::set_equal should return non-zero if sets are not equal" {
local -a first_arr=(rice beans sausage beef)
local -a second_arr=(rice beans beef)
run ar::set_equal first_arr second_arr
assert_failure

local -a first_arr=(rice beans sausage)
local -a second_arr=(rice beans beef)
run ar::set_equal first_arr second_arr
assert_failure
}

@test "ar::is_proper_subset returns 0 if set1 is a proper subset of set2" {
local -a first_arr=(rice beans sausage)
local -a second_arr=(beans sausage)
run ar::is_proper_subset second_arr first_arr
assert_success

second_arr=(rice beans sausage)
run ar::is_proper_subset second_arr first_arr
assert_failure
}

@test "ar::is_proper_superset returns 0 if set1 is a proper superset of set2" {
local -a first_arr=(rice beans sausage)
local -a second_arr=(beans sausage)
run ar::is_proper_superset first_arr second_arr
assert_success

second_arr=(rice beans sausage)
run ar::is_proper_superset first_arr second_arr
assert_failure
}
Loading