31788

Efficient map with case class as a key in Scala?

A following C code uses enum and array as efficient "map" from enum to anything:

enum Color { ColorRed, ColorGreen, ColorBlue, ColorSize}; void f() { int x[ColorSize]; x[ColorRed] = 12; x[ColorGreen] = 33; x[ColorBlue] = 4; return x[ColorGreen]; }

Is this possible with Scala? I.e. to have a "map" from case class to something, implemented as efficient array and not as tree or as hashmap. Yet I would like to be able to index only with a paricular type not with Int.

Update: In short I would like to have Scala Array indexed by some kind of enum (case class or Enumeration).

Answer1:

For small enumerations you can "simulate" the C behavior:

abstract sealed class Color(val index: Int) object Color { implicit def col2int(color:Color) = color.index } case object ColorRed extends Color(0) case object ColorGreen extends Color(1) case object ColorBlue extends Color(2) ... import Color._ val array = Array(1,2,3) array(ColorRed) = 12

However, I doubt this would be considered good style, especially because it's unsafe. Using a map is a better approach, or you could wrap an array in a specialized data structure which deals with Color indizes:

class ColorArray[T:ClassManifest] { val array = new Array[T] (3) def apply(color: Color) = array(color.index) def update(color: Color, value: T) = array(color.index) = value } ... val cArray = new ColorArray[Int]() cArray(ColorRed) = 12 println(cArray(ColorRed))

Answer2:

object Color extends Enumeration{
  val ColorRed, ColorGreen, ColorBlue = Value
}

import Color._
def f:Map[Color.Value,Int] = 
  Map(ColorRed -> 12 , ColorGreen -> 33, ColorBlue -> 4)

</pre>
    

Answer3:

If you want the full C performance you could do this:

trait CEnum { private var size = 0; def value = { size += 1; size-1 } } object Color extends CEnum { val colorRed = value val colorGreen = value val colorBlue = value val colorSize = 3 } import Color._ def f() = { val x = Array[Int](colorSize) x(colorRed) = 12 x(colorGreen) = 33 x(colorBlue) = 4 x(colorGreen) }

It's equally unsafe as the method in C & just as performant. It is however very unsafe.

Recommend

  • Check if DELETE key is pressed?
  • Co-Occurre​nce Constraint​
  • How do I configure other user defined data-type with Entity Framework Core?
  • Creating a custom InputScope for Windows Phone 7
  • Importing Excel files with a large number of columns header into mysql with c#
  • Using an enum contained in a Cloud Endpoint model on a Android client
  • MySQL: Difference between `… ADD INDEX(a); … ADD INDEX(b);` and `… ADD INDEX(a,b);`?
  • SSIS Designer is running VERY slowly
  • distinct values from multiple fields within one table ORACLE SQL
  • Dynamic ranges again - once more, with text strings
  • Android: How to correctly use NotifyDataSetChanged with SimpleExpandableListAdapter?
  • Xaml, wpf image position and crop issue
  • Inversing an interpolation of rotation
  • Configure nginx to return different files to different authenticated users with the same URI
  • NHibernate manually control fetching
  • Java color detection
  • How do I signal completion of my dataflow?
  • Convert Type Decimal to Hex (string) in .NET 3.5
  • SharedPreferences or SQLite Database?
  • Parsing a CSV string while ignoring commas inside the individual columns
  • Yii2: Config params vs. const/define
  • Avoid links criss cross / overlap in d3.js using force layout
  • Ajax Loaded meta Tags
  • Using $this when not in object context
  • Uncaught Error: Could not find module `ember-load-initializers`
  • Rearranging Cells in UITableView Bug & Saving Changes
  • VB.net deserialize, JSON Conversion from type 'Dictionary(Of String,Object)' to type '
  • KeystoneJS: Relationships in Admin UI not updating
  • Benchmarking RAM performance - UWP and C#
  • How can I get HTML syntax highlighting in my editor for CakePHP?
  • Angular 2 constructor injection vs direct access
  • Understanding cpu registers
  • How do I configure my settings file to work with unit tests?
  • Memory offsets in inline assembly
  • IndexOutOfRangeException on multidimensional array despite using GetLength check
  • Add sale price programmatically to product variations
  • Programmatically clearing map cache
  • Sorting a 2D array using the second column C++
  • Binding checkboxes to object values in AngularJs
  • java string with new operator and a literal