Merge elements from different lists in terraform 0.12 - terraform

I am trying to create a list of maps from two different lists in terraform 0.12
E.g.
List1: ["a", "b", "c"]
List2: ["aa", "bb", "cc"]
Output required:
[{
"list1element" = "a"
"list2element" = "aa"
}, {
"list1element" = "b"
"list2element" = "bb"
}, {
"list1element" = "c"
"list2element" = "cc"
}]
If I could get the index of the element in the loop this would be so easy. Nested loops also make no sense.

If you know that the two lists will always have the same length, you can use the indices from one list with the other list:
[for i, v in list1 : {
list1element = list1[i]
list2element = list2[i]
}]

Related

Calculating the number of characters inside a list in python

I made a list with some character in it and I looped through it to calculate the number of a specific character and it returns the number of all the characters inside the list and not the one's that I said it to. Take a look at my code and if someone can help I will appreciate it!
This is the code:
array = ['a', 'b', 'c', 'a']
sum_of_as = 0
for i in array:
if str('a') in array:
sum_of_as += 1
print(f'''The number of a's in this array are {sum_of_as}''')
If you know the list is only ever going to contain single letter strings, as per your example, or if you are searching for a word in a list of words, then you can simply use
list_of_strings = ["a", "b,", "c", "d", "a"]
list_of_strings.count("a")
Be aware though that will not count things such us
l = ["ba", "a", "c"] where the response would be 1 as opposed to 2 when searching for a.
The below examples do account for this, so it really does depend on your data and use case.
list_of_strings = ["a", "b,", "c", "d", "ba"]
count = sum(string.count("a") for string in list_of_strings)
print(count)
>>> 2
The above iterates each element of the list and totals up (sums) the amount of times the letter "a" is found, using str.count()
str.count() is a method that returns the number of how many times the string you supply is found in that string you call the method on.
This is the equivalent of doing
count = 0
list_of_strings = ["a", "b,", "c", "d", "ba"]
for string in list_of_strings:
count += string.count("b")
print(count)
name = "david"
print(name.count("d"))
>>> 2
The if str('a') in array evaluates to True in every for-loop iteration, because there is 'a' in the array.
Try to change the code to if i == "a":
array = ["a", "b", "c", "a"]
sum_of_as = 0
for i in array:
if i == "a":
sum_of_as += 1
print(sum_of_as)
Prints:
2
OR:
Use list.count:
print(array.count("a"))

Count duplicate string occurances in Terraform list

I am struggling with seemingly simple task in Terraform. I would easily do it with Ruby/Python with local variable inside the for loop, but Terraform doesn't have those.
Here is an issue.
I have a list with multiple duplicate string occurances:
list = ["a","b","c","a","b","c","a"]
I want to count how many times the same string occured from the beginning, but keep the count in the same location, so the resulting list would become this:
index_list = [1, 1, 1, 2, 2, 2, 3]
Is it possible with Terraform?
We can do the following:
locals {
lst = ["a", "b", "c", "a", "b", "c", "a"]
index_list = [for index, item in local.lst : length([for i in slice(local.lst, 0, index + 1) : i if i == item])]
}
output "index_list" {
value = local.index_list
}
Output for index_list:
index_list = [
1,
1,
1,
2,
2,
2,
3,
]
The first for loop iterates through the list. The second for loop is a slice combined with a filter. The slice function creates a sublist from the first element to the index if the current element. With the filter (if i == item) we filter out from this sublist all the elements which are equal to the current element. Last but not least, we get the length of this filtered list.

adding extra element to a list in terraform if condition is met

I have a list in terraform that looks something like:
array = ["a","b","c"]
Within this terraform file there are two variables called age and gender, and I want to make it so that the list called array has an extra element called "d" if age is equal to 12 and gender is equal to male (i.e. if var.age == 12 && var.gender == 'male' then array should be ["a","b","c","d"], else array should be ["a","b","c"]). Would the following going along the right path, or would I need to use another method?
array = ["a","b","c", var.age == 12 && var.gender == 'male' ? "d" : null]
There is another way to do that using flatten:
variable = flatten(["a", "b", "c", var.age == 12 ? ["d"] : []])
There are few ways you could do it. One way would be (example):
variable "array" {
default = ["a","b","c"]
}
variable "age" {
default = 12
}
variable "gender" {
default = "male"
}
locals {
array = var.age == 12 && var.gender == "male" ? concat(var.array, ["d"]) : var.array
}
output "test" {
value = local.array
}
Another approach to the problem in your particular example is removing empty elements at the end of the array.
compact is perhaps the most straightforward, but requires you to rely on using "" as a sentinel value for Emptiness.
From the documentation:
compact takes a list of strings and returns a new list with any empty string elements removed.
> compact(["a", "", "b", "c"])
[
"a",
"b",
"c",
]
I would prefer this over the other answers because it's more idiomatic. I suppose it only works for strings though.
array = compact(["a","b","c", var.age == 12 && var.gender == 'male' ? "d" : ""])`
["a","b","c"] if age != 12 and gender != male
["a","b","c", "d"] if age == 12 and gender == male
Of course the "" element could be anywhere in your list and compact would handle this optionality issue.
I would also be interested in which has the best O() performance. I don't know how compact is implemented underneath the hood, but in general you would either copy elements into a new array or you would be shifting elements into gaps left by removed elements.
I don't expect any other solution to be much better than this. Perhaps concat.
concat function pulled into terraform source code
concat source code. Just appends elements into a new slice.
Given that, it probably requires O(n) comparisons + appends, and then takes O(n) space because a new list is created.

how can I generate the list of elements of list with duplicated elements

for example if I have a list like this :
list =['a','a','a','b','b','b','c']
I want to know how many different elements are in my list and generate a list like this:
list1 = ['a','b','c']
set(list)
produces
>>> set(list)
{'b', 'a', 'c'}
If you then want it as a list you can use
list(set(list))
full_list = ["a", "b", "a", "c", "c"]
list_without_duplicaion = list(dict.fromkeys(full_list))
print(list_without_duplicaion)
Try out this answer and let me know is working as your expectations.
https://repl.it/#TamilselvanLaks/arrwithoutdup

How to get intersection of two lists in terraform?

I have two lists in terraform and want to get the intersection of these lists.
For example,
list1 = ["a", "b", "c"]
lists2 = ["b", "c", "d"]
I am looking to get output as ["b", "c"] using built-in terraform functions.
You are looking for something like this
output my_intersection {
value = setintersection( toset(var.list1), toset(var.list2) )
}

Resources