mirror of
https://github.com/hkalexling/Mango.git
synced 2026-03-20 00:00:48 -04:00
Handle library/title sorting on backend (#86)
This commit is contained in:
@@ -7,9 +7,9 @@
|
||||
require "big"
|
||||
|
||||
private class Item
|
||||
getter index : Int32, numbers : Hash(String, BigDecimal)
|
||||
getter numbers : Hash(String, BigDecimal)
|
||||
|
||||
def initialize(@index, @numbers)
|
||||
def initialize(@numbers)
|
||||
end
|
||||
|
||||
# Compare with another Item using keys
|
||||
@@ -51,57 +51,62 @@ private class KeyRange
|
||||
end
|
||||
end
|
||||
|
||||
def chapter_sort(in_ary : Array(String)) : Array(String)
|
||||
ary = in_ary.sort do |a, b|
|
||||
compare_numerically a, b
|
||||
class ChapterSorter
|
||||
@sorted_keys = [] of String
|
||||
|
||||
def initialize(str_ary : Array(String))
|
||||
keys = {} of String => KeyRange
|
||||
|
||||
str_ary.each do |str|
|
||||
scan str do |k, v|
|
||||
if keys.has_key? k
|
||||
keys[k].update v
|
||||
else
|
||||
keys[k] = KeyRange.new v
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Get the array of keys string and sort them
|
||||
@sorted_keys = keys.keys
|
||||
# Only use keys that are present in over half of the strings
|
||||
.select do |key|
|
||||
keys[key].count >= str_ary.size / 2
|
||||
end
|
||||
.sort do |a_key, b_key|
|
||||
a = keys[a_key]
|
||||
b = keys[b_key]
|
||||
# Sort keys by the number of times they appear
|
||||
count_compare = b.count <=> a.count
|
||||
if count_compare == 0
|
||||
# Then sort by value range
|
||||
b.range <=> a.range
|
||||
else
|
||||
count_compare
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
items = [] of Item
|
||||
keys = {} of String => KeyRange
|
||||
|
||||
ary.each_with_index do |str, i|
|
||||
numbers = {} of String => BigDecimal
|
||||
def compare(a : String, b : String)
|
||||
item_a = str_to_item a
|
||||
item_b = str_to_item b
|
||||
item_a.<=>(item_b, @sorted_keys)
|
||||
end
|
||||
|
||||
private def scan(str, &)
|
||||
str.scan /([^0-9\n\r\ ]*)[ ]*([0-9]*\.*[0-9]+)/ do |match|
|
||||
key = match[1]
|
||||
num = match[2].to_big_d
|
||||
|
||||
numbers[key] = num
|
||||
|
||||
if keys.has_key? key
|
||||
keys[key].update num
|
||||
else
|
||||
keys[key] = KeyRange.new num
|
||||
end
|
||||
yield key, num
|
||||
end
|
||||
|
||||
items << Item.new(i, numbers)
|
||||
end
|
||||
|
||||
# Get the array of keys string and sort them
|
||||
sorted_keys = keys.keys
|
||||
# Only use keys that are present in over half of the strings
|
||||
.select do |key|
|
||||
keys[key].count >= ary.size / 2
|
||||
end
|
||||
.sort do |a_key, b_key|
|
||||
a = keys[a_key]
|
||||
b = keys[b_key]
|
||||
# Sort keys by the number of times they appear
|
||||
count_compare = b.count <=> a.count
|
||||
if count_compare == 0
|
||||
# Then sort by value range
|
||||
b.range <=> a.range
|
||||
else
|
||||
count_compare
|
||||
end
|
||||
end
|
||||
|
||||
items
|
||||
.sort do |a, b|
|
||||
a.<=>(b, sorted_keys)
|
||||
end
|
||||
.map do |item|
|
||||
ary[item.index]
|
||||
private def str_to_item(str)
|
||||
numbers = {} of String => BigDecimal
|
||||
scan str do |k, v|
|
||||
numbers[k] = v
|
||||
end
|
||||
Item.new numbers
|
||||
end
|
||||
end
|
||||
|
||||
@@ -66,3 +66,18 @@ end
|
||||
macro render_component(filename)
|
||||
render "src/views/components/#{{{filename}}}.html.ecr"
|
||||
end
|
||||
|
||||
macro get_sort_opt
|
||||
sort_method = env.params.query["sort"]?
|
||||
|
||||
if sort_method
|
||||
is_ascending = true
|
||||
|
||||
ascend = env.params.query["ascend"]?
|
||||
if ascend && ascend.to_i? == 0
|
||||
is_ascending = false
|
||||
end
|
||||
|
||||
sort_opt = SortOptions.new sort_method, is_ascending
|
||||
end
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user