1. Two-dimensional map

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?

new topic     » topic index » view message » categorize

2. Re: Two-dimensional map

SnakeCharmer said...

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.

SnakeCharmer said...

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

new topic     » goto parent     » topic index » view message » categorize

3. Re: Two-dimensional map

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
new topic     » goto parent     » topic index » view message » categorize

4. Re: Two-dimensional map

SnakeCharmer said...

... 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.

new topic     » goto parent     » topic index » view message » categorize

5. Re: Two-dimensional map

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.

new topic     » goto parent     » topic index » view message » categorize

Search



Quick Links

User menu

Not signed in.

Misc Menu