Skip to content

Commit cf5926d

Browse files
committed
Add a function to find the index of an element in a list.
1 parent 7f738dc commit cf5926d

3 files changed

Lines changed: 56 additions & 0 deletions

File tree

config/interpolate_funcs.go

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ func init() {
2424
"file": interpolationFuncFile(),
2525
"format": interpolationFuncFormat(),
2626
"formatlist": interpolationFuncFormatList(),
27+
"index": interpolationFuncIndex(),
2728
"join": interpolationFuncJoin(),
2829
"length": interpolationFuncLength(),
2930
"replace": interpolationFuncReplace(),
@@ -178,6 +179,25 @@ func interpolationFuncFormatList() ast.Function {
178179
}
179180
}
180181

182+
// interpolationFuncIndex implements the "index" function that allows one to
183+
// find the index of a specific element in a list
184+
func interpolationFuncIndex() ast.Function {
185+
return ast.Function{
186+
ArgTypes: []ast.Type{ast.TypeString, ast.TypeString},
187+
ReturnType: ast.TypeInt,
188+
Callback: func(args []interface{}) (interface{}, error) {
189+
haystack := StringList(args[0].(string)).Slice()
190+
needle := args[1].(string)
191+
for index, element := range haystack {
192+
if needle == element {
193+
return index, nil
194+
}
195+
}
196+
return nil, fmt.Errorf("Could not find '%s' in '%s'", needle, haystack)
197+
},
198+
}
199+
}
200+
181201
// interpolationFuncJoin implements the "join" function that allows
182202
// multi-variable values to be joined by some character.
183203
func interpolationFuncJoin() ast.Function {

config/interpolate_funcs_test.go

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,39 @@ func TestInterpolateFuncFormatList(t *testing.T) {
206206
})
207207
}
208208

209+
func TestInterpolateFuncIndex(t *testing.T) {
210+
testFunction(t, testFunctionConfig{
211+
Cases: []testFunctionCase{
212+
{
213+
`${index("test", "")}`,
214+
nil,
215+
true,
216+
},
217+
218+
{
219+
fmt.Sprintf(`${index("%s", "foo")}`,
220+
NewStringList([]string{"notfoo", "stillnotfoo", "bar"}).String()),
221+
nil,
222+
true,
223+
},
224+
225+
{
226+
fmt.Sprintf(`${index("%s", "foo")}`,
227+
NewStringList([]string{"foo"}).String()),
228+
"0",
229+
false,
230+
},
231+
232+
{
233+
fmt.Sprintf(`${index("%s", "bar")}`,
234+
NewStringList([]string{"foo", "spam", "bar", "eggs"}).String()),
235+
"2",
236+
false,
237+
},
238+
},
239+
})
240+
}
241+
209242
func TestInterpolateFuncJoin(t *testing.T) {
210243
testFunction(t, testFunctionConfig{
211244
Cases: []testFunctionCase{

website/source/docs/configuration/interpolation.html.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,9 @@ The supported built-in functions are:
102102
`formatlist("instance %v has private ip %v", aws_instance.foo.*.id, aws_instance.foo.*.private_ip)`.
103103
Passing lists with different lengths to formatlist results in an error.
104104

105+
* `index(list, elem)` - Finds the index of a given element in a list. Example:
106+
`index(aws_instance.foo.*.tags.Name, "foo-test")`
107+
105108
* `join(delim, list)` - Joins the list with the delimiter. A list is
106109
only possible with splat variables from resources with a count
107110
greater than one. Example: `join(",", aws_instance.foo.*.id)`

0 commit comments

Comments
 (0)