【问题标题】:Serialize/Deserialize with a specified syntax: {1, 2, 3, 5, 8, 9} <--> "1-3, 5, 8-9"使用指定语法进行序列化/反序列化:{1, 2, 3, 5, 8, 9} <--> "1-3, 5, 8-9"
【发布时间】:2018-01-23 21:49:27
【问题描述】:

这是一种人类可读的整数数组序列化语法。

序列化后的字符串隐含一些整数,一致的整数用{start}-{end}压缩,“不一致”的元素用逗号分割。

现在,我想将排序后的int[] 序列化为string,并将string 反序列化为int[]

我怎样才能简洁地实现它?

这是一个相关问题:Split a List<int> into groups of consecutive numbers

我有一个不完美的序列化解决方案:

public string SerializationTest()
{
    var weeks = new[] { 1, 2, 3, 5, 8, 9 };
    return string.Join(", ", weeks
        .Select((e, i) => (e, i))
        .GroupBy(t => t.i - t.e)
        .Select(tg => tg.Select(t => t.e).ToArray())
        .Select(group => group.Length > 1 ? $"{group.First()}-{group.Last()}" : $"{group.Single()}"));
}

但是没有关于反序列化的想法,除了切换每个字符。

【问题讨论】:

  • 所以你在 12 小时前问了这个问题,得到了关于如何获取分组的棘手部分的答案,现在你想转换为字符串并返回整数 - 你实际上试图做什么你自己?
  • @GiladGreen 我已经补充了,这是一种人类可读的整数数组序列化语法。这是我组织中多个服务之间的数据传输语法。我觉得这个界面太糟糕了,但是我不能修改远程服务。
  • 我认为这是一个合理的问题。我所指的唯一一件事是,在 SO 上发帖时,应该显示尝试。我确定您确实尝试过解决它,但没有显示就好像您要求我们为您编写代码:)

标签: c# linq


【解决方案1】:

然后从您的 previous question 中选择任何一个实现:

var numbers = new[] { 1, 2, 3, 4, 6, 7, 9 };
var groups = numbers.GroupConsecutive();

var serialized = string.Join(", ", groups.Select(i => i.Skip(1).Any() ?
    $"{i.First()}-{i.Last()}" : $"{i.First()}"));

var deserialized = serialized.Split(new string[] { ", "}, StringSplitOptions.None)
                            .Select(i => i.Split('-').Select(s => int.Parse(s)).ToArray())
                            .SelectMany(i => i.Length == 1 ? i : Enumerable.Range(i[0], i[1] - i[0] + 1)).ToList();

【讨论】:

  • 但是 Min 或 Max 似乎会以 O(n) 遍历?
猜你喜欢
  • 2022-10-08
  • 2021-05-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-02-15
  • 1970-01-01
  • 1970-01-01
  • 2012-10-19
相关资源
最近更新 更多