动态更改不可变Map中的键的最佳方法是什么?
// I have a map like this:
const names = Map({
rya: true,
mike: false,
});
// I receive this as inputs
const inputIndex = 0;
const inputLetter = n;
// What are the operations that i need to do here to get the expected output
// [?CODE?]
// I expect this as output:
const names = Map({
ryan: true,
mike: false,
});
到目前为止我的解决方案似乎效率低下:
const namesEntrySeq = names.entrySeq();
const objectToModify = namesEntrySeq.get(inputIndex);
objectToModify[0] = objectToModify[0] + inputLetter;
const namesAsArray = namesEntrySeq.toArray();
namesAsArray[inputIndex] = objectToModify;
const names = Immutable.Map(namesAsArray);
必须有一种更优雅的方式吗?
答案 0 :(得分:2)
首先,您的输入似乎与Map一起使用是不正确的。
地图通常是HashMap。因此,这样,密钥不必遵守任何顺序。看来你的输入说:嘿,改变索引的关键" inputIndex"在密钥的末尾添加一个字母。
如果您无法更改此输入,则可能需要一个List才能按某种顺序按住键。
// do not use const here. You will need to update that reference.
let keys = List(['rya', 'mike']); // keep that updated
let names = Map({
'rya': true,
'mike': false
});
const changeKey = function (inputIndex, inputLetter) {
let key = keys.get(inputIndex);
let newKey = key + inputLetter;
names = names.withMutations(map => {
var value = map.get(key);
map.delete(key);
map.set(newKey, value);
});
keys = keys.set(inputIndex, newKey);
};
changeKey(0, 'n');
我认为这应该有用。
答案 1 :(得分:1)
如果您依赖地图中实体的顺序保持不变,则应使用OrderedMap
或Rafael said并自行跟踪订单。
如果您使用OrderedMap
,则可以使用#mapEntries
更新其中的密钥:
const names = Immutable.Map({
rya: true,
mike: false,
});
const letterToAdd = 'n';
const indexToUpdate = 0;
const updatedNames = names.mapEntries(([key, value], index) => {
if (index === indexToUpdate) {
return [key + letterToAdd, value];
} else {
return [key, value];
}
});
console.log(updatedNames);

<script src="https://cdnjs.cloudflare.com/ajax/libs/immutable/4.0.0-rc.9/immutable.js"></script>
&#13;
请注意,这是低效的,因为它会迭代地图中的每个条目以便更改一个条目。如果你的地图很小,那可能不重要。
顺便说一句,它看起来像你存储这些数据的方式有助于你想要修改它的方式。我会考虑重构您的数据,以便更容易执行您想要的操作类型。
答案 2 :(得分:0)
您可以使用mapKeys
和OrderedMap
进行此操作,因为其他人已经指出,接受输入索引会假设您的地图具有特定的顺序。
const { Map, OrderedMap, List } = require('immutable')
const names = Map({
rya: true,
mike: false,
});
const orderedNames = OrderedMap(names)
const inputKey = List(orderedNames.toSeq()).get(inputIndex)
orderedNames.mapKeys((k,v) => (k === inputKey) ? k + inputLetter : k)
et voila
Map({
ryan: true,
mike: false,
});