【问题标题】:Changing Key in immutable Map在不可变映射中更改键
【发布时间】:2018-07-28 12:30:07
【问题描述】:

在不可变 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);

一定有更优雅的方式吗?

【问题讨论】:

    标签: javascript immutable.js


    【解决方案1】:

    首先,您的输入似乎不适合与 Map 一起使用。

    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');
    

    我认为应该可以。

    【讨论】:

      【解决方案2】:

      如果您依赖于地图中实体的顺序保持不变,您应该使用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>

      请注意,这是低效的,因为它将遍历映射中的每个条目以更改一个。如果您的地图很小,则可能无关紧要。


      顺便说一句,您存储这些数据的方式似乎不利于您想要修改它的方式。我会考虑重组您的数据,以便更轻松地执行您想要对其执行的操作类型。

      【讨论】:

        【解决方案3】:

        您可以使用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)
        

        等等

        Map({
          ryan: true,
          mike: false,
        });
        

        【讨论】:

          猜你喜欢
          • 2017-10-25
          • 1970-01-01
          • 1970-01-01
          • 2021-08-25
          • 1970-01-01
          • 2017-10-15
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多