1. Two-dimensional map
- Posted by SnakeCharmer Jan 31, 2013
- 1246 views
I need structure similar to two-dimensional array, but with text indexes. How to organize such map? For example, X-keys are employees and Y-keys are assets. Value is deprecation factor.
"John Smith", "Chair" --> 0.50 "John Smith", "Computer" --> 0.99 "Kevin Fogg", "Chair" --> 0.78 "Kevin Fogg", "Computer" --> 1.5 -- he updated software at own expense
I see almost tree ways:
1. Regular map, where each key is concatenated coordinates. So, I need use key User&Stuff. It isn't so silly. I don't need to break a line in the future.
put(Deprecation, "John SmithChair", 0.50) put(Deprecation, "John SmithComputer", 0.99) put(Deprecation, "Kevin FoggChair", 0.78) put(Deprecation, "Kevin FoggComputer", 1.5)
2. The similar way, but keys unite in sequence of lines, instead of in one line.
put(Deprecation, {"John Smith", "Chair"}, 0.50) put(Deprecation, {"John Smith", "Computer"}, 0.99) put(Deprecation, {"Kevin Fogg", "Chair"}, 0.78) put(Deprecation, {"Kevin Fogg", "Computer"}, 1.5)
3. Nested maps. In other words, map of maps. I suspect that this way is ideologically best. However it is the most difficult. I will accept also the first method. I need to thrust data to "cell of array" and then to get them, having both keys. Search all values with only one of keys, search key by value, or something similar isn't required to me. What way you will advise to me?
2. Re: Two-dimensional map
- Posted by mattlewis (admin) Jan 31, 2013
- 1248 views
I need structure similar to two-dimensional array, but with text indexes. How to organize such map? For example, X-keys are employees and Y-keys are assets. Value is deprecation factor.
"John Smith", "Chair" --> 0.50 "John Smith", "Computer" --> 0.99 "Kevin Fogg", "Chair" --> 0.78 "Kevin Fogg", "Computer" --> 1.5 -- he updated software at own expense
I see almost tree ways:
1. Regular map, where each key is concatenated coordinates. So, I need use key User&Stuff. It isn't so silly. I don't need to break a line in the future.
put(Deprecation, "John SmithChair", 0.50) put(Deprecation, "John SmithComputer", 0.99) put(Deprecation, "Kevin FoggChair", 0.78) put(Deprecation, "Kevin FoggComputer", 1.5)
2. The similar way, but keys unite in sequence of lines, instead of in one line.
put(Deprecation, {"John Smith", "Chair"}, 0.50) put(Deprecation, {"John Smith", "Computer"}, 0.99) put(Deprecation, {"Kevin Fogg", "Chair"}, 0.78) put(Deprecation, {"Kevin Fogg", "Computer"}, 1.5)
I would prefer 2 over 1, since it seems cleaner.
3. Nested maps. In other words, map of maps. I suspect that this way is ideologically best. However it is the most difficult. I will accept also the first method. I need to thrust data to "cell of array" and then to get them, having both keys. Search all values with only one of keys, search key by value, or something similar isn't required to me. What way you will advise to me?
Why do you think that nested maps would be difficult? We have nested_put and nested_get for doing exactly this.
I might suggest something like the following, which allows you to look things up by either asset or employee:
include std/map.e map employees = map:new() map assets = map:new() map depreciations = map:new() public procedure add_depreciation( sequence employee_name, sequence asset_name, atom depreciation_value ) map:nested_put( employees, {employee_name, asset_name}, 1 ) map:nested_put( asset_name, {asset_name, employee_name}, 1 ) map:put( depreciations, { employee_name, asset_name }, depreciation_value ) end procedure public function get_depreciation( sequence employee_name, sequence asset_name ) return map:get( depreciations, { employee_name, asset_name }, 0 ) end function public function get_employee_depreciations( sequence employee_name ) sequence employee_depreciation = {} atom emp_map = map:get( employees, employee_name ) if map( emp_map ) then sequence employee_assets = map:keys( emp_map ) for i = 1 to length( employee_assets ) do employee_depreciation = append( employee_depreciation, { employee_assets[i], map:get( depreciations, { employee_name, employee_assets[i] }, 0 ) } ) end for end if return employee_depreciation end function public function get_asset_depreciations( sequence asset_name ) sequence asset_depreciation = {} atom asset_map = map:get( assets, asset_name ) if map( asset_map ) then sequence asset_employees = map:keys( asset_map ) for i = 1 to length( asset_employees ) do asset_depreciation = append( asset_depreciation, { asset_employees[i], map:get( depreciations, { asset_employees[i], asset_name }, 0 ) } ) end for end if return asset_depreciation end function
Matt
3. Re: Two-dimensional map
- Posted by SnakeCharmer Jan 31, 2013
- 1261 views
Thanks, I started understanding at last. However it is too flexible and superfluous in my situation. I attentively read about an nested puts and gets and understood that it is equivalent to my second way. What way is more effective? What is better - nested maps (about 150x150 entries) or one big map (about 20000 entries)? How to optimize the map if it is known in advance that it never will exceed a certain size and its elements will never be removed or change.
I know about "new(THRESHOLD)". May be, it is better do:
public constant THRESHOLD = 150 map XXX = new(THRESHOLD) -- for every map
4. Re: Two-dimensional map
- Posted by DerekParnell (admin) Feb 01, 2013
- 1227 views
... What way is more effective? What is better ... ? How to optimize the map ...?
The first rule of optimization is "do not optimize anything before you have to".
Write your application using any algorithm that makes sense to you, disregarding any optimization ideas. And THEN if its too slow for you, start profiling it to see which sections of code would benefit from optimization ... you may be surprised as to what you find out.
5. Re: Two-dimensional map
- Posted by CoJaBo2 Feb 02, 2013
- 1193 views
Another thing to consider would be storing things in a database-
Will you ever need to do things like "find the total and/or average depreciation values for all chairs" or "find all items with depreciation values less than .5 or greater than 1"?
Those things are fast and trivial in SQL, but not easily doable using maps.