Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Removing (with del) multiple items from an array can result in indexing problems #2027

Open
nicktimko opened this issue May 2, 2024 · 0 comments
Labels

Comments

@nicktimko
Copy link

Describe the bug
If removing multiple elements from an array, it seems like yq is computing where they are before doing any of the modifications, then removing those indicies, but as they get removed, the previously-calculated indicies are wrong.

Note that any how to questions should be posted in the discussion board and not raised as an issue.

Version of yq: 4.43.1
Operating system: macOS 14.4.1
Installed via: Homebrew

Input Yaml
names.yml:

{"ppl":[{"name":"alice"},{"name":"bob"},{"name":"charlie"},{"name":"deb"}]}

Script

#!/bin/bash

input='{"ppl":[{"name":"alice"},{"name":"bob"},{"name":"charlie"},{"name":"deb"}]}'
tmp_names=/tmp/names
jq <<<$input >$tmp_names.json

python3 -c "import platform;print(platform.platform())"
jq --version
yq --version

jq 'del(.ppl[] | select(.name == "alice")) | del(.ppl[] | select(.name == "bob"))' $tmp_names.json
yq 'del(.ppl[] | select(.name == "alice")) | del(.ppl[] | select(.name == "bob"))' $tmp_names.json
yq 'del(.ppl[] | select(.name == "bob")) | del(.ppl[] | select(.name == "alice"))' $tmp_names.json

Output

macOS-14.4.1-arm64-arm-64bit
jq-1.7.1
yq (https://github.com/mikefarah/yq/) version v4.43.1
{
  "ppl": [
    {
      "name": "charlie"
    },
    {
      "name": "deb"
    }
  ]
}
{
  "ppl": [
    {
      "name": "bob"  # [Ed: added comment] !!!
    },
    {
      "name": "deb"
    }
  ]
}
{
  "ppl": [
    {
      "name": "charlie"
    },
    {
      "name": "deb"
    }
  ]
}

Additional context
Feels kinda like this toy Python example, though here it will blow up if it tries to remove an out-of-bounds index, while if you change "bob" to "deb" in the yq example, then you wind up with it outputting bob/charlie/deb.

a = ['a', 'b', 'c', 'd']
to_remove = ['a', 'b']
for idx in [a.index(x) for x in to_remove]:
    a.pop(idx)
print(a)  #>>> ['b', 'd']
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

1 participant