2017-10-21 24 views
1

这是我有什么,我想要实现:为什么在mutableList上的.map实际上并没有改变Kotlin中List的值?

  1. 我有具有mutableList作为现场的一类。

  2. 我想找到该列表中的特定元素并进行更改。

这是我到目前为止已经试过:

  1. 这是我希望的功能的语句会工作,之后我也把它放在一个扩展功能:

    fun Classroom.setNewParameters(id: String, modifiedName: String) { 
        this.students.filter { l -> l.id == id } 
           .map { l -> l.name = modifiedName } 
           .toList() 
    } 
    

    但是在调用该函数后,列表students看起来没有改变。

  2. 我发现下面的代码的“丑陋”的解决方案:

    fun Classroom.setNewParameters(id: String, modifiedName: String) { 
        for (l : Student in this.students) { 
         if (l.id == id) { 
          l.name = modifiedName 
          break 
         } 
        } 
    } 
    

不过寿,我真的很想知道为什么第一个代码块的行为就像它没有按和”实际上对列表有任何影响。

+0

我无法重现(但是你严重滥用map():没有理由创建一个新列表来改变原始列表中的一个元素)。 https://gist.github.com/jnizet/a25b87ff33ca156f446adbc8d6548bac。发布完整的最小程序来重现您的问题。 –

+0

@JBNizet是的,你是对的,那完全不是很酷。我不知道为什么我被困在.map中(真实情况稍微复杂一点,但仍然没有意义使用.map)。我在下面发布了一个很好的答案,但他删除了它,无论如何他只是告诉我去'students.forEach({if(it.id == id)it.name = modifiedName})'这似乎工作得很好!你认为这是一个好的解决方案吗? –

+5

不,我想你应该使用'list.find {it.id == id} ?. name = modifiedName'。这就是匹配你的第二个代码片段:用给定的id找到* first *元素,然后改变它的名字。 –

回答

0

您可以将map作为转换输入以获取新输出的方式。通常情况下它不应该内部发生变异的状态,换句话说,它应该是没有副作用的功能追求可维护性

在你的情况,你显然希望变异的元素,你可能想使用的代码片段:

fun Classroom.setNewParameters(id: String, modifiedName: String) { 
    this.students.filter { l -> l.id == id } 
       .onEach { l -> l.name = modifiedName } 
} 

而且,即使你使用正确map应该必须修改现场l.name(除非你已经实现了你自己的代表或的getter/setter)。尝试在上调试设置断点,并查看过滤后是否还有剩余项目

0

Noob here,但是我前几天看到与此相关的内容。

是否有一个原因,你不会只是检查,看看你的数组是否包含旧值,返回元素ID,然后分配你的新值到该ID?

我想我只是指出,这可以用“value in array”类型的搜索来完成......但我仍然太新以至于不知道使用它与地图的优缺点。

的这样一种之下,这是我从Kotlin - Idiomatic way to check array contains value


“值” 在阵列

它转换到Java API有:

阵列。包含(“值”)


所以我检查的旧值在数组中,返回它的索引,然后重新分配新值指标。

相关问题