Removing empty strings from a list

I am trying to build a list of names from a list of objects. It works fine, but some of the objects don’t have a name. No problem, I use the default() filter to set those elements of my list to empty strings, like this:

Build a list of names from a list of things

  • set_fact:
    names: “{{ names |default() + [ item.name |default(‘’) ] }}”
    with_items: “{{ things }}”

This got me, as expected, this result (because at the moment, my test list of things has two items, and neither has a name attribute):

ok: [localhost] => {
“names”: [
“”,
“”
]
}

Now, how can I remove those empty strings from my list? I have read numerous articles that mention “rejectattr”, but I don’t understand how to use it.

I tried this:

Remove any empty elements from the list of instance profile names

  • set_fact:
    names: “{{ names |default() |reject(‘equalto’, ‘’) }}”

And got this mystifying output:

ok: [localhost] => {
“names”: “<generator object _select_or_reject at 0x7f4ecd9c9aa0>”
}

I also tried using rejectattr on the first loop like this:

Build a list of names from a list of things

  • set_fact:
    names: “{{ names |default() + [ item.name |default(‘’) ] }}”
    with_items: “{{ things |rejectattr(‘name’, ‘undefined’) }}”

That got me a list with ONE empty string:

ok: [localhost] => {
“names”: [
“”
]
}

Grateful for any pointers…

Regards, K.

PS: Pointers to USEFUL, COMPLETE examples of how to use rejectattr(), reject() and so on would be useful too. All the examples I have found seem to assume a huge amount of knowledge I don’t have, or are tiny fragments of code…

I am trying to build a list of names from a list of objects. It works fine, but some of the objects don’t have a name. No problem, I use the default() filter to set those elements of my list to empty strings, like this:

Build a list of names from a list of things

  • set_fact:
    names: “{{ names |default() + [ item.name |default(‘’) ] }}”
    with_items: “{{ things }}”

This got me, as expected, this result (because at the moment, my test list of things has two items, and neither has a name attribute):

ok: [localhost] => {
“names”: [
“”,
“”
]
}

Now, how can I remove those empty strings from my list? I have read numerous articles that mention “rejectattr”, but I don’t understand how to use it.

Well, the easiest way is not to put them in there in the first place.

`

  • set_fact:
    names: “{{ things | selectattr(‘name’, ‘defined’) | map(attribute=‘name’) | list }}”

`

I tried this:

Remove any empty elements from the list of instance profile names

  • set_fact:
    names: “{{ names |default() |reject(‘equalto’, ‘’) }}”

And got this mystifying output:

ok: [localhost] => {
“names”: “<generator object _select_or_reject at 0x7f4ecd9c9aa0>”
}

map(), select(), and friends return generators; use the list filter (as I’ve done above) to convert it to a list.

PS: Pointers to USEFUL, COMPLETE examples of how to use rejectattr(), reject() and so on would be useful too. All the examples I have found seem to assume a huge amount of knowledge I don’t have, or are tiny fragments of code…

They’re very simple filters, so useful, complete examples are going to be tiny fragments of code. http://jinja.pocoo.org/docs/latest/templates/#rejectattr

Thanks, flowerysong.

I went with this:

  • set_fact:
    names:
  • set_fact:
    names: “{{ names + [ item.name ] }}”
    with_items: “{{ things |selectattr(‘name’, ‘defined’) |list }}”

I want to have the list even if it is empty, that’s why there are now two set_fact calls.

As far as the examples being complete, I have to disagree. These are ALL the examples for rejectattr() on the page you linked:

{{ users|rejectattr("is_active") }}
{{ users|rejectattr("email", "none") }}

Unanswered questions:

  • what is “is_active”?
  • what is “email”?
  • what is “none”?
  • what is “users”?
  • what are the results of using the two examples?

This filter (like most of the others) needs far more complete documentation. It should provide a sample “users” variable, and sample output for the two examples. It should describe clearly what each of the possible parameters to the filter is.

I have no idea whether ANY of the following is correct:

I’m assuming that users is a structured list and that “is_active” and “email” are attributes of the elements of that list, e.g.:

vars:
users:

  • name: Fred Nurk"
    email: fred@example.com
    is_active: true

  • name: “Bob McBobson”
    email: bob@example.com
    is_active: false

  • name: “Mary Nurk”
    is_active: true

I’m also guessing that “none” is some sort of filter. It’s described as a “test” - where are these tests documented? There is no description of it or link to other documentation, so I really have no idea. It may be selecting users where the email address is the literal string value “none”.

Give the above sample “users” variable, I am guessing that the expected output of the two examples, if assigned to x, would be:

x:

  • name: “Fred Nurk”
    email: fred@example.com
    is_active: true
  • name: “Mary Nurk”
    is_active: true

x:

Please don’t just tell me I am free to write the documentation myself :slight_smile: This is constructive criticism, not a complaint.

Regards, K.