更改不可变映射中的键

时间:2018-02-17 22:05:18

标签: javascript immutable.js

动态更改不可变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);

必须有一种更优雅的方式吗?

3 个答案:

答案 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)

如果您依赖地图中实体的顺序保持不变,则应使用OrderedMapRafael 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;
&#13;
&#13;

请注意,这是低效的,因为它会迭代地图中的每个条目以便更改一个条目。如果你的地图很小,那可能不重要。

顺便说一句,它看起来像你存储这些数据的方式有助于你想要修改它的方式。我会考虑重构您的数据,以便更容易执行您想要的操作类型。

答案 2 :(得分:0)

您可以使用mapKeysOrderedMap进行此操作,因为其他人已经指出,接受输入索引会假设您的地图具有特定的顺序。

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,
});