-
-
Notifications
You must be signed in to change notification settings - Fork 9.9k
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
Adds group_by_exp filter #5513
Adds group_by_exp filter #5513
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
literally nothing
😆
I'm thinking I need a |
5c8de61
to
1d163de
Compare
Current version actually works and groups stuff. I need to learn one or thing or two about Liquid parsing to implement @caspervonb's example fully, though. I'm working on that. Rubocop is also complaning about the size of |
fe4e672
to
8a96f6f
Compare
@caspervonb: can you take a look if this is what you had in mind? |
itens... OCD 😭 The result looks correct but we should probaly yield the same object type as group_by? A group has a name (the value it was grouped by), an array of items and a size (group.items.size == group.size) Relevant should "allow filters in expression" do
items = [
{ "version"=>"1.0", "result"=>"slow" },
{ "version"=>"1.1.5", "result"=>"medium" },
{ "version"=>"2.7.3", "result"=>"fast" }
]
result = @filter.group_by_exp(items, "item", "item.version | split: '.' | first")
expected = [
{
"name" => "1",
"items" => [
{ "version"=>"1.0", "result"=>"slow" },
{ "version"=>"1.1.5", "result"=>"medium" },
]
},
{
"name" => "2",
"items" => { "version"=>"2.7.3", "result"=>"fast" }
},
]
assert_equal expected, result
end But yeah its grouping by the expression, filters and all so 👍 |
😆 |
Awesome, @caspervonb! Will take a look at that next. See 679a0c1#diff-77a9bfa5e00815266a775b7f497e3595 |
These tests should cover everything I think, tho may want to add some more coverage for more complex expressions context "group_by_exp filter" do
should "successfully group array of Jekyll::Page's" do
@filter.site.process
grouping = @filter.group_by_exp(@filter.site.pages, "page", "page.layout | upcase")
grouping.each do |g|
assert(
["DEFAULT", "NIL", ""].include?(g["name"]),
"#{g["name"]} isn't a valid grouping."
)
case g["name"]
when "DEFAULT"
assert(
g["items"].is_a?(Array),
"The list of grouped items for 'default' is not an Array."
)
assert_equal 5, g["items"].size
when "nil"
assert(
g["items"].is_a?(Array),
"The list of grouped items for 'nil' is not an Array."
)
assert_equal 2, g["items"].size
when ""
assert(
g["items"].is_a?(Array),
"The list of grouped items for '' is not an Array."
)
assert_equal 15, g["items"].size
end
end
should "include the size of each grouping" do
grouping = @filter.group_by_exp(@filter.site.pages, "page", "page.layout")
grouping.each do |g|
p g
assert_equal(
g["items"].size,
g["size"],
"The size property for '#{g["name"]}' doesn't match the size of the Array."
)
end
end
should "be equivalent of group_by" do
grouping = @filter.group_by_exp(@filter.site.pages, "page", "page.layout")
expected = @filter.group_by(@filter.site.pages, "layout")
assert_equal grouping, expected
end
end |
# "items" => [...] } # all the items where `property` == "larry" | ||
def group_by(input, property) | ||
if groupable?(input) | ||
groups = input.group_by { |item| item_property(item, property).to_s } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I did this mostly because Rubocop was complaining about module length. But I'm torn about this refactoring mostly because of this call to item_property
. This line got moved to the new module, but keeps calling code on the original one. In other words, the new module is bound to be included by the old one.
Should we keep this as per this commit? Should we extract this common code to a third module? Should we break the original Filters
module in a completely different way?
I'm mostly happy about this PR now. But some feedback on the way I split the |
This is done at 7f18ac8. Let me know if you need any help merging this. |
a2c0be1
to
04837ac
Compare
04837ac
to
7f18ac8
Compare
Think you merged that link/commitish into non existence ;) |
Yeah. Will rebuild it. |
Might as-well do RDoc comments too! # Group an array of items by an expression
#
# input - the object array
# variable - the variable to assign each item to in the expression
# expression -a Liquid comparison expression passed in as a string
#
# Returns the filtered array of objects |
# "items" => [...] } # all the items where `property` == "larry" | ||
def group_by(input, property) | ||
if groupable?(input) | ||
groups = input.group_by { |item| item_property(item, property).to_s } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I did this to make Rubocop happy. But I'm torn about this refactoring and the main reason is this call to item_property
. It binds the new module to being included to the old one.
Should we keep this as is? Should we split item_property
to its own module? Should we split Filters
in a totally different way?
Yeah, sure! |
@caspervonb: I fixed the link and edited the comment. Sorry. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This LGTM once CI passes. 👌
end | ||
|
||
private | ||
def make_grouped_array(groups) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't like the name of this method – something about Ruby conventions which I always loved is that the method could be considered like a variable, so you name things as though they aren't dynamic. In this case, you'd remove make_
and just have grouped_array(groups)
or group_metadata_array(groups)
. Would either of those suit you?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
something about Ruby conventions which I always loved is that the method could be considered like a variable
Totally agree! That is something I appreciate in Ruby too.
I guess I've been dayjobbing on Javaland for too long, though. ;-)
Would either of those suit you?
Sure. I chose grouped_array(groups)
. See 91f0b91
should "include the size of each grouping" do | ||
groups = @filter.group_by_exp(@filter.site.pages, "page", "page.layout") | ||
groups.each do |g| | ||
p g |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Whoops!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
;-)
@parkr I've finally got around to fixing this. CI is now passing. Let me know if you want this to be squashed/rebased. |
Looks great to me, thank you! @jekyllbot: merge +minor |
Great, thanks for the work @thiagoarrais 👍 |
You're welcome, @caspervonb. Let me know if you choose to use this in jsperf. |
* master: (40 commits) Update history to reflect merge of #5658 [ci skip] Fix a couple of typos in the docs Update history to reflect merge of #5657 [ci skip] Update variables.md Update history to reflect merge of #5653 [ci skip] Improve Permalinks documentation. Update history to reflect merge of #5652 [ci skip] Use `assert_nil` instead of `assert_equal nil` Update history to reflect merge of #5513 [ci skip] Ignore symlinked file in windows Update history to reflect merge of #5612 [ci skip] Update history to reflect merge of #5643 [ci skip] Update Core team list in README Update history to reflect merge of #5641 [ci skip] use backticks for Gemfile for consistency since in the next sentence _config.yml file has backtick add a set of steps in site_configuration.feature update documentation for Windows narrow it down to only Windows revert and adjust site_configuration.feature add 'tzinfo-data' gem to generated Gemfile ...
Tasklist:
{% data | group_by_exp: "item", "item" %}
{% data | group_by_exp: "item", "item.version" %}
{% data | group_by_exp: "item", "item.version | split: '.' | first" %}
Fixes #5415.