class EL_ARRAYED_MAP_LIST
Client examples: ADD_ALBUM_ART_TASK ; CONTAINER_STRUCTURE_TEST_SET ; CSV_STATE_PARSER ; EIFFEL_CONFIGURATION_FILE ; EL_STRING_POOL ; GROUPED_TABLE_TEST_SET ; ID3_FRAME_CODE_CLASS_GENERATOR ; NOTE_EDITOR_COMMAND ; STOCK_CONSUMPTION_CALCULATOR ; UNDEFINE_PATTERN_COUNTER_COMMAND
Arrayed list of key-value pair tuples
EL_ARRAYED_MAP_LIST [K, G] EL_KEY_INDEXED_ARRAYED_MAP_LIST [K -> COMPARABLE, G] EL_CONFORMING_INSTANCE_TYPE_MAP [G] EL_HASHABLE_KEY_ARRAYED_MAP_LIST [K -> HASHABLE, G] EL_STYLED_TEXT_LIST* [S -> STRING_GENERAL] EL_STYLED_STRING_8_LIST EL_STYLED_STRING_32_LIST EL_STYLED_ZSTRING_LIST EL_APPLICATION_HELP_LIST EL_DECOMPRESSED_DATA_LIST EL_STRING_POOL [S -> STRING_GENERAL create make end] EL_BOOK_ASSEMBLY
note
description: "Arrayed list of key-value pair tuples"
descendants: "See end of class"
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: "2024-09-30 15:45:55 GMT (Monday 30th September 2024)"
revision: "37"
class
EL_ARRAYED_MAP_LIST [K, G]
inherit
EL_ARRAYED_LIST [K]
rename
do_all as do_all_keys,
extend as key_extend,
first as first_key,
last as last_key,
make_from_array as make_from_key_array,
item as item_key,
i_th as i_th_key,
is_sortable as is_key_sortable,
has as has_key,
put_front as put_key_front,
replace as replace_key,
sort as sort_by_key,
search as search_key
export
{NONE} append, duplicate, key_extend, merge_left, merge_right,
put_key_front, prune, prune_all, put_left, put_right,
remove_left, remove_right, swap
redefine
make, new_cursor, remove, sort_by_key, wipe_out, grow, resize, trim
end
EL_CONTAINER_CONVERSION [G]
rename
as_structure as as_value_structure
undefine
copy, is_equal
end
EL_SHARED_FACTORIES
create
make, make_filled, make_from, make_empty, make_from_array,
make_from_keys, make_from_table, make_from_values
feature {NONE} -- Initialization
make (n: INTEGER)
do
Precursor (n)
create internal_value_list.make (n)
end
make_from_array (array: like MANIFEST_ARRAY)
do
make (array.count)
across array as list loop
extend (list.item.key, list.item.value)
end
end
make_from_keys (keys: CONTAINER [K]; to_value: FUNCTION [K, G])
-- make from container of `keys' using `to_value' to generate value for each key
require
valid_function: as_structure (keys).valid_open_argument (to_value)
local
l_value_list: EL_ARRAYED_RESULT_LIST [K, G]
do
if keys.is_empty then
make_empty
else
make_from (keys)
create l_value_list.make (keys, to_value)
internal_value_list := l_value_list.to_list
end
end
make_from_table (table: TABLE_ITERABLE [G, K])
do
make (Iterable.count (table))
across table as value loop
extend (value.key, value.item)
end
end
make_from_values (values: CONTAINER [G]; to_key: FUNCTION [G, K])
-- make from container of `values' using `to_key' to generate key for each value
require
valid_function: as_value_structure (values).valid_open_argument (to_key)
local
l_key_list: EL_ARRAYED_RESULT_LIST [G, K]
do
if values.is_empty then
make_empty
else
create internal_value_list.make_from (values)
create l_key_list.make (values, to_key)
make_from_special (l_key_list.area)
end
end
feature -- Access
item_tuple: TUPLE [key: K; value: G]
require
valid_item_key: not off
do
Result := [item_key, internal_value_list [index]]
end
key_list: EL_ARRAYED_LIST [K]
do
create Result.make_from_special (area_v2.twin)
if object_comparison then
Result.compare_objects
end
end
new_cursor: EL_ARRAYED_MAP_ITERATION_CURSOR [K, G]
do
create Result.make (Current)
end
feature -- Conversion
to_grouped_list_table: EL_GROUPED_LIST_TABLE [G, HASHABLE]
do
if attached {like to_grouped_list_table} new_grouped_table (Grouped_list_type) as table then
Result := table
fill_grouped (table)
end
end
to_grouped_set_table: EL_GROUPED_SET_TABLE [G, HASHABLE]
do
if attached {like to_grouped_set_table} new_grouped_table (Grouped_set_type) as table then
Result := table
fill_grouped (table)
end
end
feature -- Value items
first_value: like item_value
require
valid_count: count > 0
do
Result := internal_value_list.first
end
i_th_value (i: INTEGER): like item_value
require
valid_index: valid_index (i)
do
Result := internal_value_list [i]
end
item_value: G
require
valid_index: valid_index (index)
do
Result := internal_value_list [index]
end
last_value: like item_value
require
valid_count: count > 0
do
Result := internal_value_list.last
end
value_list: EL_ARRAYED_LIST [G]
do
create Result.make_from_special (internal_value_list.area.twin)
if value_object_comparison then
Result.compare_objects
end
end
feature -- Status query
has (pair: like item_tuple): BOOLEAN
do
push_cursor
start; search_key (pair.key)
if found then
if object_comparison then
Result := internal_value_list [index] ~ pair.value
else
Result := internal_value_list [index] = pair.value
end
end
pop_cursor
end
is_value_sortable: BOOLEAN
do
Result := Eiffel.is_comparable_type (({G}).type_id)
end
value_object_comparison: BOOLEAN
do
Result := internal_value_list.object_comparison
end
feature -- Element change
extend (key: K; value: G)
do
key_extend (key)
internal_value_list.extend (value)
end
put_front (key: K; value: G)
do
put_key_front (key)
internal_value_list.put_front (value)
end
put_i_th_value (a_value: G; i: INTEGER)
require
valid_index: valid_index (i)
do
internal_value_list.put_i_th (a_value, i)
end
replace (key: K; value: G)
do
replace_key (key)
internal_value_list.put_i_th (value, index)
end
replace_value (value: G)
require
valid_item: not off
do
internal_value_list.put_i_th (value, index)
end
set_key_item (key: like item_key; value: like item_value)
-- set first `item.value' with key matching `key' or else extend with new key-value tuple
-- key comparison is either by object or reference depending on `object_comparison'
do
push_cursor
start; search_key (key)
if found then
internal_value_list.put_i_th (value, index)
else
extend (key, value)
end
pop_cursor
end
set_last_value (a_value: G)
local
i: INTEGER
do
i := internal_value_list.count
if i > 0 then
internal_value_list.put_i_th (a_value, i)
end
end
feature -- Status setting
compare_value_objects
-- Ensure that future search operations will use `equal'
-- rather than `=' for comparing references.
do
internal_value_list.compare_objects
end
compare_value_references
-- Ensure that future search operations will use `='
-- rather than `equal' for comparing references.
do
internal_value_list.compare_references
end
feature -- Basic operations
do_all (action: PROCEDURE [K, G])
local
i: INTEGER
do
if attached internal_value_list.area_v2 as value_area
and then attached area_v2 as key_area
then
from until i = key_area.count loop
action (key_area [i], value_area [i])
i := i + 1
end
end
end
sort_by_key (in_ascending_order: BOOLEAN)
do
if attached {SPECIAL [COMPARABLE]} area as comparables then
sort_comparables (comparables, in_ascending_order)
end
end
sort_by_value (in_ascending_order: BOOLEAN)
require
sortable_by_value: is_value_sortable
do
if attached {SPECIAL [COMPARABLE]} internal_value_list.area as comparables then
sort_comparables (comparables, in_ascending_order)
end
end
feature -- Removal
remove
do
internal_value_list.go_i_th (index)
internal_value_list.remove
Precursor
end
wipe_out
do
Precursor
internal_value_list.wipe_out
end
feature -- Resizing
grow (i: INTEGER)
-- Change the capacity to at least `i'.
do
Precursor (i)
internal_value_list.grow (i)
end
resize (new_capacity: INTEGER)
-- Resize list so that it can contain
-- at least `n' items. Do not lose any item.
do
Precursor (new_capacity)
internal_value_list.resize (new_capacity)
end
trim
do
Precursor
internal_value_list.trim
end
feature -- Type definitions
MANIFEST_ARRAY: ARRAY [like item_tuple]
-- type of array used to initialize `Current' in `make_from_array' routine
require
never_called: False
do
create Result.make_empty
end
feature {NONE} -- Implementation
fill_grouped (table: like to_grouped_list_table)
local
i: INTEGER
do
if attached {SPECIAL [HASHABLE]} area as key_area
and then attached internal_value_list.area as value_area
then
from i := 0 until i = key_area.count loop
table.extend (key_area [i], value_area [i])
i := i + 1
end
end
end
new_grouped_table (type: TYPE [ANY]): HASH_TABLE [ANY, HASHABLE]
do
if value_object_comparison then
Result := Hash_table_factory.new_equal_item (type, << {G}, {K} >>, count)
else
Result := Hash_table_factory.new_item (type, << {G}, {K} >>, count)
end
end
sort_comparables (comparables: SPECIAL [COMPARABLE]; in_ascending_order: BOOLEAN)
local
sorted: EL_SORTED_INDEX_LIST
do
create sorted.make (comparables, in_ascending_order)
reorder (sorted)
internal_value_list.reorder (sorted)
end
feature {ARRAYED_LIST_ITERATION_CURSOR} -- Internal attributes
internal_value_list: EL_ARRAYED_LIST [G];
feature {NONE} -- Constants
Grouped_list_type: TYPE [ANY]
once
Result := {EL_GROUPED_LIST_TABLE [ANY, HASHABLE]}
end
Grouped_set_type: TYPE [ANY]
once
Result := {EL_GROUPED_SET_TABLE [ANY, HASHABLE]}
end
invariant
same_key_value_counts: count = internal_value_list.count
note
descendants: "[
EL_ARRAYED_MAP_LIST [K, G]
${EL_KEY_INDEXED_ARRAYED_MAP_LIST [K -> COMPARABLE, G]}
${EL_CONFORMING_INSTANCE_TYPE_MAP [G]}
${EL_HASHABLE_KEY_ARRAYED_MAP_LIST [K -> HASHABLE, G]}
${EL_STYLED_TEXT_LIST* [S -> STRING_GENERAL]}
${EL_STYLED_STRING_8_LIST}
${EL_STYLED_STRING_32_LIST}
${EL_STYLED_ZSTRING_LIST}
${EL_APPLICATION_HELP_LIST}
${EL_DECOMPRESSED_DATA_LIST}
${EL_STRING_POOL [S -> STRING_GENERAL create make end]}
${EL_BOOK_ASSEMBLY}
]"
end