不可变集合到“序列化”字符串

时间:2018-02-01 18:54:17

标签: serialization deserialization immutable.js

我希望采用不可变结构并将其字符串化为磁盘上的文件,以便可以将其重新评估为等效结构。例如:

收藏品:

const obj = Immutable.OrderedMap({
  "key1": "value",
  "key2": [1, 2, 3],
});

所需的字符串化版本:

import Immutable from 'immutable';

export default Immutable.OrderedMap([
  ["key1", "value"],
  ["key2", [1, 2, 3]],
]);

如果我们确定我们只会遇到地图和列表,我们就可以'fromJS(' + JSON.stringify(obj)) + ')',但是一旦得到OrderedMap s,Set等内容,这种做法就不会工作(失去秩序,在重新水化时使所有东西成为地图或清单)。

是否有现成的方法来实现这一目标?

1 个答案:

答案 0 :(得分:0)

在没有现有方法的情况下,我提出了以下建议:

function stringifyImmutable(obj) {
  let prefix = '';
  let value = ''
  let suffix = '';

  if (obj === undefined) {
    value = 'undefined';
  }
  else if (obj === null) {
    value = 'null';
  }
  else if (
    typeof obj === 'number' ||
    typeof obj === 'string' ||
    typeof obj === 'boolean'
  ) {
    value = JSON.stringify(obj);
  }
  else if (Array.isArray(obj)) {
    prefix = '[';
    value = obj.map((value) => stringifyImmutable(value));
    suffix = ']';
  }
  else if (obj instanceof Immutable.OrderedMap) {
    prefix = 'Immutable.OrderedMap([';
    value = Array.from(obj.entries()).map((item) => stringifyImmutable(item));
    suffix = '])';
  }
  else if (obj instanceof Immutable.OrderedSet) {
    prefix = 'Immutable.OrderedSet([';
    value = Array.from(obj.entries()).map((item) => stringifyImmutable(item));
    suffix = '])';
  }
  else if (obj instanceof Immutable.Set) {
    prefix = 'Immutable.Set([';
    value = Array.from(obj.values()).map((item) => stringifyImmutable(item));
    suffix = '])';
  }
  else if (obj instanceof Immutable.Map) {
    prefix = 'Immutable.Map([';
    value = obj.reduce(
      (items, value, key) => {
        items.push(`[\n${stringifyImmutable(key)},\n${stringifyImmutable(value)}\n]`);

        return items;
      },
      []
    );
    suffix = '])';
  }
  else if (obj instanceof Immutable.List) {
    prefix = 'Immutable.List([';
    value = obj.map((item) => stringifyImmutable(item)).toArray();
    suffix = '])';
  }
  else {
    prefix = '{';
    value = Object.keys(obj).reduce(
      (items, key) => {
        items.push(`${key}: ${stringifyImmutable(obj[key])}`);

        return items;
      },
      []
    );
    suffix = '}';
  }

  if (Array.isArray(value)) {
    if (value.length === 0) {
      value = '';
    }
    else {
      value = '\n' + value.join(`,\n`) + '\n';
    }
  }

  return `${prefix || ''}${value}${suffix || ''}`;
}

这不会产生格式良好的输出(没有缩进),但它似乎有效。我使用ESLint对其进行格式化,因为我的项目已经在使用ESLint:

// See https://eslint.org/docs/developer-guide/nodejs-api for documentation on the
    // ESLint Node API
    const engine = new eslint.CLIEngine({
      fix: true,
    });

    const results = engine.executeOnText(fileContent).results[0];

如果使用带有isImmutable()的v4.0.0-rc.9,这可能会更简单。