Как я могу сериализовать кортежи как список в F #? - PullRequest
1 голос
/ 15 января 2020

У меня есть библиотека, которая отправляет мне результаты, которые включают в себя кортежи. Мне нужно обработать некоторые данные, сериализовать их, а затем они отправляются в другую систему.

кортежи ВСЕГДА состоят из 2 значений, но они чрезвычайно расточительны при сериализации:

(3, 4)

будет сериализовано как:

{"Item1":3,"Item2":4}

, тогда как

[3; 4]

будет сериализовано как:

[3,4]

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

Есть ли способ на уровне сериализатора преобразовать кортежи в список?

синтаксический анализатор следующего процесса может быть легко изменен для размещения список вместо кортежей, так что это кажется лучшим сценарием.

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

1 Ответ

5 голосов
/ 15 января 2020

Вы можете переопределить поведение сериализации по умолчанию, указав свой JsonConverter. В следующем примере показан модуль форматирования, который записывает int * int кортежи в виде двухэлементных JSON массивов.

open Newtonsoft.Json

type IntIntConverter() = 
  inherit JsonConverter<int * int>()
  override x.WriteJson(writer:JsonWriter, (a:int,b:int), serializer:JsonSerializer) =
    writer.WriteStartArray()
    writer.WriteValue(a)
    writer.WriteValue(b)
    writer.WriteEndArray()

  override x.ReadJson(reader, objectType, existingValue, hasExistingValue, serializer) = 
    (0, 0)

let sample = [ (1,2); (3,4) ]
let json = JsonConvert.SerializeObject(sample, Formatting.None, IntIntConverter())

Результат выполнения этого будет [[1,2],[3,4]]. Обратите внимание, что я не реализовал метод ReadJson, поэтому вы еще не можете разобрать кортежи. Это потребует дополнительной работы, но вы можете посмотреть на существующие JsonConverter s, чтобы увидеть, как это должно быть сделано.

Также обратите внимание, что это для определенного типа кортежа c, содержащего два целых числа. Если вам нужно поддерживать другие кортежи, вам, вероятно, потребуется предоставить несколько вариантов конвертера.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...