associate 和 associateBy 一样吗?

huangapple go评论176阅读模式
英文:

Are associate and associateBy the same?

问题

我对associateBy的两个参数版本感到困惑:

inline fun <T, K, V> Iterable<T>.associateBy(
    keySelector: (T) -> K,
    valueTransform: (T) -> V
): Map<K, V>

这似乎与associate做的事情完全相同,只是有不同的语法:

inline fun <T, K, V> Iterable<T>.associate(
    transform: (T) -> Pair<K, V>
): Map<K, V>

等效用法:

listOf("cat", "dog", "mouse").associateBy({it.toUpperCase()}, {it.length})
listOf("cat", "dog", "mouse").associate({it.toUpperCase() to it.length})

这两个函数只是相同功能的不同语法,还是它们分别存在的特定技术原因,例如,每一个是否设计用于不同的情况?

英文:

I'm confused by the two-parameter variant of associateBy:

inline fun &lt;T, K, V&gt; Iterable&lt;T&gt;.associateBy(
    keySelector: (T) -&gt; K,
    valueTransform: (T) -&gt; V
): Map&lt;K, V&gt;

This seems to do exactly the same thing as associate, but with alternative syntax:

inline fun &lt;T, K, V&gt; Iterable&lt;T&gt;.associate(
    transform: (T) -&gt; Pair&lt;K, V&gt;
): Map&lt;K, V&gt;

Equivalent usages:

listOf(&quot;cat&quot;, &quot;dog&quot;, &quot;mouse&quot;).associateBy({it.toUpperCase()}, {it.length})
listOf(&quot;cat&quot;, &quot;dog&quot;, &quot;mouse&quot;).associate({it.toUpperCase() to it.length})

Are these two functions just alternative syntax for the same thing, or is there a specific technical reason they both exist separately, e.g. is each one designed to be used in a different circumstance than the other?

答案1

得分: 2

是的,它们只是执行相同操作的替代方法。不过,我可以想到一些情况下,你可能更喜欢其中一种方法。

如果键和值来自一个耗时的函数,你不想为每个元素运行两次,那么associate更适合:

list.associate {
    val result = timeConsumingFunction(it) // timeConsumingFunction只在每个元素上运行一次
    result.property1 to result.property2
}

如果键和值与元素的属性/方法引用很好地映射,那么对于真正喜欢属性/方法引用的人(比如我),associateBy看起来更好:

list.associateBy(Foo::property1, Foo::property2)

associatedBy还避免了创建Pair对象,而associate在大多数情况下需要,尽管这在大多数情况下是微小的优化。

英文:

Yes, they are just alternative ways of doing the same thing. I can think of some situations where you would prefer one of them though.

If the keys and values come from a time consuming function that you don't want to run twice for each element, then associate is more suitable:

list.associate {
    val result = timeConsumingFunction(it) // timeConsumingFunction only gets run once per element
    result.property1 to result.property2
}

If the keys and values map nicely to property/method references of the elements, associateBy looks nicer to people who really likes property/method references (e.g. me):

list.associateBy(Foo::property1, Foo::property2)

associatedBy also avoids creating the Pair object that associate would require, though this is a micro-optimisation in most cases.

huangapple
  • 本文由 发表于 2023年7月3日 18:47:41
  • 转载请务必保留本文链接:https://go.coder-hub.com/76604016.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定