branquito branquito - 5 months ago 12
Ruby Question

Return elements from one array, based on values from another one

Writing a plugin for Jekyll, I am stucked at some ruby related code as I am not yet familiar on
how to do

.select
,
.map
and all their friends on arrays (except for simple one array cases)

So my problem now is, having this as an array of docs, with their related
sha1sum
codes:

[
[
#<Jekyll::Document _projects/1st-project.md collection=projects>,
"8f918a3d8263a957c206a9864d3507aaa5277a79"
],
[
#<Jekyll::Document _posts/2nd-project.markdown collection=posts>,
"ca81eda5d49100bdf23db16fe1c9d17040fd33f8"
],
[
#<Jekyll::Document _posts/3rd-project.markdown collection=posts>,
"37bf18464b00c9a808436853bc6d868aff218eb6"
],
...
...
]


And on the other side, the hash of linkage groups like so:

{
"linkage_groups"=>
[
{
"group_name"=>"test1",
"sha1_sums"=> [
"ca81eda5d49100bdf23db16fe1c9d17040fd33f8",
"37bf18464b00c9a808436853bc6d868aff218eb6"
]
},
{
"group_name"=>"test1",
"sha1_sums"=> [
"154c255d59e6063fc609ade2254dc1b09d1de8ab",
"3e9ef9f059786888e39df608d104263cf0fdae76"
]
}
]
}


How would I be able to cycle through these groups one at a time, and return for each group of
sha1_sums
docs from the above
array where
sha1_sum
of a document is present in a particular group.

Expected output would be an array of hashes for each of the groups, holding
docs which fulfill the condition, on their
sha1_sum
being present in a group:

Ex. 2nd and 3rd project fulfill the condition because their
sha's
are in a group named
test1


[
{
"test1" => [#<Jekyll::Document _posts/2nd-project.markdown collection=posts>, #<Jekyll::Document _posts/3rd-project.markdown collection=posts]
},
{
"test2" => [..., ...]
},
{
"test3" => [..., ...]
},
...
]


As of reply from @Lukas Baliak -

Here is what I am getting in case of both hashes belonging to the same group:

{
"ca81eda5d49100bdf23db16fe1c9d17040fd33f8"=>"test1",
"b673be35ad73ab48da23b271ab0dda95ea07c905"=>"test1",
"154c255d59e6063fc609ade2254dc1b09d1de8ab"=>"test2",
"3e9ef9f059786888e39df608d104263cf0fdae76"=>"test2"
}

[
[
#<Jekyll::Document _projects/my-first-project.md collection=projects>,
"b673be35ad73ab48da23b271ab0dda95ea07c905"
],
[
#<Jekyll::Document _posts/2016-06-05-one-more-post.markdown collection=posts>,
"ca81eda5d49100bdf23db16fe1c9d17040fd33f8"
]
]

{
"test1"=> [#<Jekyll::Document _posts/2016-06-05-one-more-post.markdown collection=posts>, "ca81eda5d49100bdf23db16fe1c9d17040fd33f8"]
}


Only one document is listed, why? Where is
b673be35ad73ab48da23b271ab0dda95ea07c905
?

Answer

I preffer to use simple data structures, so i "migrate" groups to Hash

doc

doc = [
  [
    "#<Jekyll::Document _projects/my-first-project.md collection=projects>",
    "8f918a3d8263a957c206a9864d3507aaa5277a79"
  ],
  [
   "#<Jekyll::Document _posts/2016-06-05-one-more-post.markdown collection=posts>",
    "ca81eda5d49100bdf23db16fe1c9d17040fd33f8"
  ]
]

group_config

group_config = {
  "linkage_groups" => [
    {
      "group_name" => "test1",
      "sha1_sums" => [
        "ca81eda5d49100bdf23db16fe1c9d17040fd33f8",
        "b673be35ad73ab48da23b271ab0dda95ea07c905"
      ]
    },
    {
      "group_name" => "test2",
      "sha1_sums" => [
        "154c255d59e6063fc609ade2254dc1b09d1de8ab",
        "8f918a3d8263a957c206a9864d3507aaa5277a79"
      ]
    }
  ]
}

Migrate to Hash

groups = group_config["linkage_groups"].each_with_object({}) do |h, exp|
  h["sha1_sums"].each { |sha1| exp[sha1] = h["group_name"] }
end

export groups

p groups

# {
#   "ca81eda5d49100bdf23db16fe1c9d17040fd33f8" => "test1",
#   "b673be35ad73ab48da23b271ab0dda95ea07c905" => "test1",
#   "154c255d59e6063fc609ade2254dc1b09d1de8ab" => "test2",
#   "8f918a3d8263a957c206a9864d3507aaa5277a79" => "test2"
# }

And process to generate hash structure

export = doc.each_with_object({}) do |arr, exp|
  exp[groups[arr[1]]] = arr
end

output

p export

# {
#   "test2" => ["#<Jekyll::Document _projects/my-first-project.md collection=projects>", "8f918a3d8263a957c206a9864d3507aaa5277a79"],
#   "test1" => ["#<Jekyll::Document _posts/2016-06-05-one-more-post.markdown collection=posts>", "ca81eda5d49100bdf23db16fe1c9d17040fd33f8"]
# }

EDIT:

If you need more then one use this modification

export = doc.each_with_object(Hash.new{|k, v| k[v] = []}) do |arr, exp|
  exp[groups[arr[1]]] << arr
end

EDIT 2

Ok, if you need one sha1_hash in to more groups may be you can use this update.

groups = group_config["linkage_groups"].each_with_object(Hash.new { |k, v| k[v] = [] }) do |h, exp|
  h["sha1_sums"].each { |sha1| exp[sha1] << h["group_name"] }
end

groups

p groups

# {
#   "ca81eda5d49100bdf23db16fe1c9d17040fd33f8" => ["test1"],
#   "b673be35ad73ab48da23b271ab0dda95ea07c905" => ["test1"],
#   "8f918a3d8263a957c206a9864d3507aaa5277a79" => ["test1", "test2"],
#   "154c255d59e6063fc609ade2254dc1b09d1de8ab" => ["test2"]
# }

process

export = doc.each_with_object(Hash.new { |k, v| k[v] = [] }) do |arr, exp|
  groups[arr[1]].each { |group| exp[group] << arr }
end

output

p export

# {
#   "test1" => [
#     ["#<Jekyll::Document _projects/my-first-project.md collection=projects>", "8f918a3d8263a957c206a9864d3507aaa5277a79"],
#     ["#<Jekyll::Document _posts/2016-06-05-one-more-post.markdown collection=posts>", "ca81eda5d49100bdf23db16fe1c9d17040fd33f8"]
#   ],
#   "test2" => [
#     ["#<Jekyll::Document _projects/my-first-project.md collection=projects>", "8f918a3d8263a957c206a9864d3507aaa5277a79"],
#     ["#<Jekyll::Document _posts/2016-06-0s-one-more-post.markdown collection=posts>", "154c255d59e6063fc609ade2254dc1b09d1de8ab"]
#   ]
# }

I hope this will helps.