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

'Foreach' confusion #1281

Closed
ghost opened this issue Nov 30, 2016 · 1 comment
Closed

'Foreach' confusion #1281

ghost opened this issue Nov 30, 2016 · 1 comment

Comments

@ghost
Copy link

ghost commented Nov 30, 2016

I have file like this:

[
    { "id": 1, "name": "A", "dep_id": 2 },
    { "id": 2, "name": "B", "dep_id": 3 },
    { "id": 3, "name": "C", "dep_id": 4 },
    { "id": 4, "name": "D", "dep_id": null }
]

It contains simple dependency chain. Now, I'm trying to get rid of identifiers and transform this file to something like this:

[
    { name: "A", dep_name: "B" },
    { name: "B", dep_name: "C" },
    { name: "C", dep_name: "D" },
    { name: "D", dep_name: null }
]

My first idea is to use foreach function, but there is something I don't understand (or it won't work).

Here is my starting point, output as expected:

.[] as $items | foreach $items as $item ({}; $item; {name: .name, dep_id: .dep_id})

{
  "name": "A",
  "dep_id": 2
}
{
  "name": "B",
  "dep_id": 3
}
{
  "name": "C",
  "dep_id": 4
}
{
  "name": "D",
  "dep_id": null
}

Next, print dependencies:

.[] as $items | foreach $items as $item ({}; $items | select(.id == ($item | .dep_id)); .name)

Output is empty. Why?
Let's use some constant id:

.[] as $items | foreach $items as $item ({}; $items | select(.id == 2); .name)

"B"

Well, no. It should be as below, because the same item is (seems to be) selected four times:

"B"
"B"
"B"
"B"

Obviously, I'm missing something. The longer I read the docs, the more I'm confused.
Is this solvable with jq?

@pkoppstein
Copy link
Contributor

The following filter produces the results you want given the input you provided:

. as $in
| reduce range(1; length+1) as $i
   ([]; . + [ {name: $in[$i-1].name, "dep_name": $in[$i].name }] )

This particular filter ignores dep_id and so may not be exactly what you need, but rest assured, it can be done in jq.

Since the "Issues" section is primarily for bug reports and enhancement requests, in future, please post usage questions at stackoverflow.com using the jq tag:

https://stackoverflow.com/questions/tagged/jq

@ghost ghost closed this as completed Oct 20, 2019
This issue was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant