복붙노트

[SCALA] 지도 별 키에 컬렉션을 돌려 스칼라 가장 좋은 방법은?

SCALA

지도 별 키에 컬렉션을 돌려 스칼라 가장 좋은 방법은?

내가 타입 T의 컬렉션 C를 가지고 T에 p 속성이있는 경우 (유형 P, 말의), 맵별로 추출 키를 할 수있는 가장 좋은 방법은 무엇입니까?

val c: Collection[T]
val m: Map[P, T]

한 가지 방법은 다음과 같다 :

m = new HashMap[P, T]
c foreach { t => m add (t.getP, t) }

하지만 지금은 변경 가능한지도가 필요합니다. 은 1 개 라인의 내가 불변의지도로 끝날 정도로이 일을 더 좋은 방법이 있나요? (물론 나는 자바에서와 마찬가지로 나는 간단한 라이브러리 유틸리티로 위를 돌 수 있었다, 그러나 나는 스칼라 필요가 없다고 생각한다)

해결법

  1. ==============================

    1.당신이 사용할 수있는

    당신이 사용할 수있는

    c map (t => t.getP -> t) toMap
    

    그러나이 2 개 순회 필요하다는 인식.

  2. ==============================

    2.당신은 튜플의 변수 번호와지도를 구성 할 수 있습니다. 변수 인수로 결과를 변환 _ * 트릭 : 그래서를 사용하여 다음 튜플의 집합으로 변환하기 위해 컬렉션지도 방법을 사용합니다.

    당신은 튜플의 변수 번호와지도를 구성 할 수 있습니다. 변수 인수로 결과를 변환 _ * 트릭 : 그래서를 사용하여 다음 튜플의 집합으로 변환하기 위해 컬렉션지도 방법을 사용합니다.

    scala> val list = List("this", "maps", "string", "to", "length") map {s => (s, s.length)}
    list: List[(java.lang.String, Int)] = List((this,4), (maps,4), (string,6), (to,2), (length,6))
    
    scala> val list = List("this", "is", "a", "bunch", "of", "strings")
    list: List[java.lang.String] = List(this, is, a, bunch, of, strings)
    
    scala> val string2Length = Map(list map {s => (s, s.length)} : _*)
    string2Length: scala.collection.immutable.Map[java.lang.String,Int] = Map(strings -> 7, of -> 2, bunch -> 5, a -> 1, is -> 2, this -> 4)
    
  3. ==============================

    3.@ 제임스 Iry의 용액에 더하여, 배를 사용하여 이러한 작업을 수행하는 것도 가능하다. 나는이 솔루션은 빠르게 튜플 방법 (적은 쓰레기 object의 작성)보다 약간 것으로 의심 :

    @ 제임스 Iry의 용액에 더하여, 배를 사용하여 이러한 작업을 수행하는 것도 가능하다. 나는이 솔루션은 빠르게 튜플 방법 (적은 쓰레기 object의 작성)보다 약간 것으로 의심 :

    val list = List("this", "maps", "string", "to", "length")
    val map = list.foldLeft(Map[String, Int]()) { (m, s) => m(s) = s.length }
    
  4. ==============================

    4.이것은 다음과 같이 수집을 접음으로써 불변 단일 통과로 구현 될 수있다.

    이것은 다음과 같이 수집을 접음으로써 불변 단일 통과로 구현 될 수있다.

    val map = c.foldLeft(Map[P, T]()) { (m, t) => m + (t.getP -> t) }
    

    불변 맵에 추가하는 추가 항목을 가진 새로운 불변지도를 리턴하고이 값이 스크롤 동작을 통해 어큐뮬레이터로서 작용하기 때문에 상기 용액을 작동한다.

    여기에 트레이드 오프는 그 효율성에 비해 코드의 단순함이다. 그래서, 큰 컬렉션에 대해,이 방법은지도 toMap인가 2- 순회 구현을 사용하는 것보다 더 적합 할 수있다.

  5. ==============================

    5.또 다른 해결책 (모든 종류의 작동하지 않을 수 있습니다)

    또 다른 해결책 (모든 종류의 작동하지 않을 수 있습니다)

    import scala.collection.breakOut
    val m:Map[P, T] = c.map(t => (t.getP, t))(breakOut)
    

    이 여기에 중간 목록의 생성, 더 많은 정보를 피할 수 : 스칼라 2.8 브레이크 아웃

  6. ==============================

    6.당신이 달성하려고하는 것은 조금 정의되지 않습니다. 무엇 C에서 두 개 이상의 항목이 동일한 페이지를 공유하는 경우? 어떤 항목이지도에서 해당 페이지에 매핑 할 것인가?

    당신이 달성하려고하는 것은 조금 정의되지 않습니다. 무엇 C에서 두 개 이상의 항목이 동일한 페이지를 공유하는 경우? 어떤 항목이지도에서 해당 페이지에 매핑 할 것인가?

    이보고의보다 정확한 방법은 p와 그것을 가지고 모든 C 항목 사이의지도를 산출한다 :

    val m: Map[P, Collection[T]]
    

    이것은 쉽게 GROUPBY을 달성 할 수있다 :

    val m: Map[P, Collection[T]] = c.groupBy(t => t.p)
    

    당신은 여전히 ​​원래지도를 원하는 경우, 예를 들어, 그것을있는 첫 번째 t에 페이지를 매핑 할 수 있습니다 :

    val m: Map[P, T] = c.groupBy(t => t.p) map { case (p, ts) =>  p -> ts.head }
    
  7. ==============================

    7.이것은 아마도 매핑 목록을 설정하는 가장 효율적인 방법은 아니지만 호출하는 코드를 읽기 수 있습니다. 나는 목록에 mapBy 방법을 추가하는 암시 적 변환을 사용 :

    이것은 아마도 매핑 목록을 설정하는 가장 효율적인 방법은 아니지만 호출하는 코드를 읽기 수 있습니다. 나는 목록에 mapBy 방법을 추가하는 암시 적 변환을 사용 :

    implicit def list2ListWithMapBy[T](list: List[T]): ListWithMapBy[T] = {
      new ListWithMapBy(list)
    }
    
    class ListWithMapBy[V](list: List[V]){
      def mapBy[K](keyFunc: V => K) = {
        list.map(a => keyFunc(a) -> a).toMap
      }
    }
    

    코드 예제를 호출 :

    val list = List("A", "AA", "AAA")
    list.mapBy(_.length)                  //Map(1 -> A, 2 -> AA, 3 -> AAA)
    

    참고 때문에 암시 적 변환의 발신자 코드는 수입 스칼라의 implicitConversions 할 필요가있다.

  8. ==============================

    8.

    c map (_.getP) zip c
    

    잘 작동하고 매우 intuitiv입니다

  9. ==============================

    9.어떻게 우편 및 toMap 사용에 대한?

    어떻게 우편 및 toMap 사용에 대한?

    myList.zip(myList.map(_.length)).toMap
    
  10. ==============================

    10.무엇의 가치를 들어, 여기에 그 일을 두 가지 의미가 가지 방법이 있습니다 :

    무엇의 가치를 들어, 여기에 그 일을 두 가지 의미가 가지 방법이 있습니다 :

    scala> case class Foo(bar: Int)
    defined class Foo
    
    scala> import scalaz._, Scalaz._
    import scalaz._
    import Scalaz._
    
    scala> val c = Vector(Foo(9), Foo(11))
    c: scala.collection.immutable.Vector[Foo] = Vector(Foo(9), Foo(11))
    
    scala> c.map(((_: Foo).bar) &&& identity).toMap
    res30: scala.collection.immutable.Map[Int,Foo] = Map(9 -> Foo(9), 11 -> Foo(11))
    
    scala> c.map(((_: Foo).bar) >>= (Pair.apply[Int, Foo] _).curried).toMap
    res31: scala.collection.immutable.Map[Int,Foo] = Map(9 -> Foo(9), 11 -> Foo(11))
    
  11. ==============================

    11.이것은 나를 위해 작동합니다 :

    이것은 나를 위해 작동합니다 :

    val personsMap = persons.foldLeft(scala.collection.mutable.Map[Int, PersonDTO]()) {
        (m, p) => m(p.id) = p; m
    }
    

    지도는 변경 가능해야하고,지도는지도를 반환하지 않는 가변지도에 추가 이후 반환되어야합니다.

  12. ==============================

    12.컬렉션 사용지도는 () toMap에 따라

    컬렉션 사용지도는 () toMap에 따라

    val map = list.map(e => (e, e.length)).toMap
    
  13. from https://stackoverflow.com/questions/674639/scala-best-way-of-turning-a-collection-into-a-map-by-key by cc-by-sa and MIT license