class EL_SORTED_MAP_INDEX_LIST
Extended EL_SORTED_INDEX_LIST to sort EL_ARRAYED_MAP_LIST containers by both key and value
note
description: "[
Extended ${EL_SORTED_INDEX_LIST} to sort ${EL_ARRAYED_MAP_LIST} containers by both key and value
]"
author: "Finnian Reilly"
copyright: "Copyright (c) 2001-2022 Finnian Reilly"
contact: "finnian at eiffel hyphen loop dot com"
license: "MIT license (See: en.wikipedia.org/wiki/MIT_License)"
date: "2025-01-25 16:35:41 GMT (Saturday 25th January 2025)"
revision: "1"
class
EL_SORTED_MAP_INDEX_LIST
inherit
EL_SORTED_INDEX_LIST
rename
make as make_sorted
redefine
less_than
end
create
make
feature {NONE} -- Initialization
make (a_target, a_group_items: SPECIAL [COMPARABLE]; in_ascending_order, ascending_group: BOOLEAN)
require
same_size_arrays: a_target.count = a_group_items.count
local
i, last_index, lower_i, upper_i, max_group_count, item_count: INTEGER
group_intervals: EL_ARRAYED_INTERVAL_LIST; group_item: COMPARABLE
group_index_area: SPECIAL [INTEGER]
do
group_items := a_group_items
make_sorted (a_target, in_ascending_order)
if in_ascending_order /= ascending_group and count > 1 then
-- reverse indexed order of each group
create group_intervals.make ((count // 10).max (10))
if attached area as index_area and then attached target as t then
lower_i := 0; upper_i := 0; group_item := t [lower_i]
last_index := count - 1
group_item := t [index_area [0]]
from i := 1 until i > last_index loop
if group_item ~ t [index_area [i]] then
upper_i := i
else
group_intervals.extend (lower_i, upper_i)
lower_i := i; upper_i := i
group_item := t [index_area [i]]
end
i := i + 1
end
group_intervals.extend (lower_i, last_index)
if attached group_intervals as list then
from list.start until list.after loop
if list.item_count > max_group_count then
max_group_count := list.item_count
end
list.forth
end
create group_index_area.make_empty (max_group_count)
from list.start until list.after loop
group_index_area.wipe_out
lower_i := list.item_lower; upper_i := list.item_upper
item_count := upper_i - lower_i + 1
if item_count > 1 then
from i := upper_i until i < lower_i loop
group_index_area.extend (index_area [i])
i := i - 1
end
index_area.copy_data (group_index_area, 0, lower_i, item_count)
end
list.forth
end
end
end
end
end
feature {NONE} -- Implementation
less_than (i_1, i_2: INTEGER): BOOLEAN
do
if attached target as t then
if t [i_1] ~ t [i_2] then
if attached group_items as g then
Result := g [i_1] < g [i_2]
end
else
Result := t [i_1] < t [i_2]
end
end
end
feature {NONE} -- Internal attributes
group_items: SPECIAL [COMPARABLE]
end