Update item_property to return numbers as numbers instead of strings (#6608)

Merge pull request 6608
This commit is contained in:
Kelly-Ann Green 2018-07-09 01:25:32 -04:00 committed by jekyllbot
parent caa0846e7b
commit f4fcfbdaa0
2 changed files with 28 additions and 13 deletions

View File

@ -299,16 +299,16 @@ module Jekyll
# We also utilize the Schwartzian transform to make this more efficient. # We also utilize the Schwartzian transform to make this more efficient.
def sort_input(input, property, order) def sort_input(input, property, order)
input.map { |item| [item_property(item, property), item] } input.map { |item| [item_property(item, property), item] }
.sort! do |apple_info, orange_info| .sort! do |a_info, b_info|
apple_property = apple_info.first a_property = a_info.first
orange_property = orange_info.first b_property = b_info.first
if !apple_property.nil? && orange_property.nil? if !a_property.nil? && b_property.nil?
- order - order
elsif apple_property.nil? && !orange_property.nil? elsif a_property.nil? && !b_property.nil?
+ order + order
else else
apple_property <=> orange_property a_property <=> b_property || a_property.to_s <=> b_property.to_s
end end
end end
.map!(&:last) .map!(&:last)
@ -317,15 +317,22 @@ module Jekyll
def item_property(item, property) def item_property(item, property)
if item.respond_to?(:to_liquid) if item.respond_to?(:to_liquid)
property.to_s.split(".").reduce(item.to_liquid) do |subvalue, attribute| property.to_s.split(".").reduce(item.to_liquid) do |subvalue, attribute|
subvalue[attribute] parse_sort_input(subvalue[attribute])
end end
elsif item.respond_to?(:data) elsif item.respond_to?(:data)
item.data[property.to_s] parse_sort_input(item.data[property.to_s])
else else
item[property.to_s] parse_sort_input(item[property.to_s])
end end
end end
# return numeric values as numbers for proper sorting
def parse_sort_input(property)
number_like = %r!\A\s*-?(?:\d+\.?\d*|\.\d+)\s*\Z!
return property.to_f if property =~ number_like
property
end
def as_liquid(item) def as_liquid(item)
case item case item
when Hash when Hash

View File

@ -1074,10 +1074,6 @@ class TestFilters < JekyllUnitTest
end end
should "return sorted strings" do should "return sorted strings" do
assert_equal %w(10 2), @filter.sort(%w(10 2)) assert_equal %w(10 2), @filter.sort(%w(10 2))
assert_equal(
[{ "a" => "10" }, { "a" => "2" }],
@filter.sort([{ "a" => "10" }, { "a" => "2" }], "a")
)
assert_equal %w(FOO Foo foo), @filter.sort(%w(foo Foo FOO)) assert_equal %w(FOO Foo foo), @filter.sort(%w(foo Foo FOO))
assert_equal %w(_foo foo foo_), @filter.sort(%w(foo_ _foo foo)) assert_equal %w(_foo foo foo_), @filter.sort(%w(foo_ _foo foo))
# Cyrillic # Cyrillic
@ -1090,6 +1086,18 @@ class TestFilters < JekyllUnitTest
assert_equal [{ "a" => 1 }, { "a" => 2 }, { "a" => 3 }, { "a" => 4 }], assert_equal [{ "a" => 1 }, { "a" => 2 }, { "a" => 3 }, { "a" => 4 }],
@filter.sort([{ "a" => 4 }, { "a" => 3 }, { "a" => 1 }, { "a" => 2 }], "a") @filter.sort([{ "a" => 4 }, { "a" => 3 }, { "a" => 1 }, { "a" => 2 }], "a")
end end
should "return sorted by property array with numeric strings sorted as numbers" do
assert_equal([{ "a" => ".5" }, { "a" => "0.65" }, { "a" => "10" }],
@filter.sort([{ "a" => "10" }, { "a" => ".5" }, { "a" => "0.65" }], "a"))
end
should "return sorted by property array with numeric strings first" do
assert_equal([{ "a" => ".5" }, { "a" => "0.6" }, { "a" => "twelve" }],
@filter.sort([{ "a" => "twelve" }, { "a" => ".5" }, { "a" => "0.6" }], "a"))
end
should "return sorted by property array with numbers and strings " do
assert_equal([{ "a" => "1" }, { "a" => "1abc" }, { "a" => "20" }],
@filter.sort([{ "a" => "20" }, { "a" => "1" }, { "a" => "1abc" }], "a"))
end
should "return sorted by property array with nils first" do should "return sorted by property array with nils first" do
ary = [{ "a" => 2 }, { "b" => 1 }, { "a" => 1 }] ary = [{ "a" => 2 }, { "b" => 1 }, { "a" => 1 }]
assert_equal [{ "b" => 1 }, { "a" => 1 }, { "a" => 2 }], @filter.sort(ary, "a") assert_equal [{ "b" => 1 }, { "a" => 1 }, { "a" => 2 }], @filter.sort(ary, "a")