Подтвердить что ты не робот

JSON строит набор

Как бы JSON.stringify() a Set?

Вещи, которые не работали в Chromium 43:

var s = new Set(['foo', 'bar']);

JSON.stringify(s); // -> "{}"
JSON.stringify(s.values()); // -> "{}"
JSON.stringify(s.keys()); // -> "{}"

Я бы ожидал получить нечто похожее на сериализованный массив.

JSON.stringify(["foo", "bar"]); // -> "["foo","bar"]"
4b9b3361

Ответ 1

JSON.stringify не работает напрямую с наборами, поскольку данные, хранящиеся в наборе, не сохраняются как свойства.

Но вы можете преобразовать набор в массив. Тогда вы сможете правильно его выровнять.

Любое из следующих действий выполнит трюк:

JSON.stringify([...s]);
JSON.stringify([...s.keys()]);
JSON.stringify([...s.values()]);
JSON.stringify(Array.from(s));
JSON.stringify(Array.from(s.keys()));
JSON.stringify(Array.from(s.values()));

Ответ 2

В то время как во всех вышеперечисленных работах я предлагаю вам установить подкласс и добавить метод toJSON, чтобы убедиться, что он правильно строит. Особенно, если вы будете часто выступать. Я использую наборы в своих магазинах Redux и должен убедиться, что это никогда не было проблемой.

Это базовая реализация. Именование - это просто, чтобы проиллюстрировать точку выбора вашего собственного стиля.

class JSONSet extends Set {
    constructor(iterable) {
        super(iterable)
    }

    toJSON () {
        return [...this]
    }
}

const set = new JSONSet([1, 2, 3])
console.log(JSON.stringify(set))

Ответ 3

Используйте этот JSON.stringify replacer:

function Set_toJSON(key, value) {
  if (typeof value === 'object' && value instanceof Set) {
    return [...value];
  }
  return value;
}

Тогда:

const fooBar = { foo: new Set([1, 2, 3]), bar: new Set([4, 5, 6]) };
JSON.stringify(fooBar, Set_toJSON)

Результат:

"{"foo":[1,2,3],"bar":[4,5,6]}"