从json数组

时间:2017-07-26 18:38:31

标签: c# json linq

以下是该问题的简要说明。 从服务器我得到的json数组看起来与此相似:

    [
  {
    "messagenumber": "0529069f-a403-4eea-a955-430a10995745",
    "message": "A",
    "partnumber": 1,
    "total": 3
  },
  {
    "messagenumber": "0529069f-a403-4eea-a955-430a10995745",
    "message": "B",
    "partnumber": 2,
    "total": 3
  },
  {
    "messagenumber": "0529069f-a403-4eea-a955-430a10995745",
    "message": "C",
    "partnumber": 3,
    "total": 3
  },
  {
    "messagenumber": "52e7d68d-462b-46b9-8eec-f289bcdf7b06",
    "message": "AA",
    "partnumber": 1,
    "total": 2
  }......
]

它代表消息部分列表。属于同一组的消息部分具有相同的消息编号部分编号表示订单编号。在客户端,我必须最后组合属于同一组的所有消息部分并呈现完整的消息。从上面的示例中,对于单个消息,结果将如下所示:

var msg = new FullMessage();
msg.MessageNumber = "0529069f-a403-4eea-a955-430a10995745";
msg.Message = "ABC"; //here we have full message created out of 3 parts
msg.PartNumber = 1; //not important 
msg.Total = 1 //also not important

,最终结果应该是FullMessage对象的集合。 此外,应忽略部分消息(并非所有部分都存在)。

使用LINQ语句可以优雅地完成吗?

感谢您的任何建议。

5 个答案:

答案 0 :(得分:2)

这应该做你想要的:

var myList = new List<FullMessage>();
myList.GroupBy(msg => msg.MessageNumber)
      .Where(grouping => grouping.Count() == grouping.First().Total)
      .Select(grouping => grouping.OrderBy(x => x.order))
      .Select(grouping => grouping.Select(x => x.Message)
      .Aggregate((x, y) => x + y)); 

这是做什么的:

  1. MessageNumber
  2. 对邮件进行分组
  3. 过滤掉所有部分讯息
  4. PartNumber订阅每个分组的所有邮件,以确保所有内容的顺序正确无误
  5. 浏览所有分组并选择所有消息
  6. 汇总邮件
  7. 结果是连接字符串的枚举。

答案 1 :(得分:0)

试试这段代码:

Backgroundworker

答案 2 :(得分:0)

让我们说消息看起来像是

public class FullMessage
{
    public string MessageNumber { get; set; }
    public string Message { get; set; }
    public int PartNumber { get; set; }
    public int Total { get; set; }
}

以下是我可能解决方案的想法:

  1. 按消息编号分组
  2. 按组件编号
  3. 对组中的每封邮件进行排序
  4. 使用Aggregate
  5. 组合消息部分并计算新FullMessage对象中的总数(不确定是否需要计数以便这是可选的)

    结果是这个LINQ查询:

    IEnumerable<FullMessage> combinedMessages = messages.GroupBy(m => m.MessageNumber)
        .Select(g => g.OrderBy(m => m.PartNumber)
        .Aggregate(new FullMessage() { MessageNumber = g.Key }, (r, m) =>
        {
            r.Message += m.Message;
            //Not sure if counting up is required in your code
            //so the following line is optional
            r.Total += m.Total;
            return r;
        }));
    

答案 3 :(得分:0)

以下示例代码:

void Main()
{
    // Testing mocked data
    var data = new List<ServerMessagePart> {
        new ServerMessagePart{
            Messagenumber = "0529069f-a403-4eea-a955-430a10995745",
            Message= "A",
            Partnumber= 1,
            Total = 3
        },
        new ServerMessagePart{
            Messagenumber = "0529069f-a403-4eea-a955-430a10995745",
            Message= "C",
            Partnumber= 3,
            Total = 3
        },
        new ServerMessagePart{
            Messagenumber = "0529069f-a403-4eea-a955-430a10995745",
            Message= "B",
            Partnumber= 2,
            Total = 3
        },
        new ServerMessagePart{
            Messagenumber = "52e7d68d-462b-46b9-8eec-f289bcdf7b06",
            Message= "AA",
            Partnumber= 1,
            Total = 2
        }
    };

    // Compiled messages
    var messages = new List<ServerMessage>();

    // Process server partial messages - group parsts by message number
    var partialMessages = data.GroupBy(x => x.Messagenumber);
    foreach(var messageParts in partialMessages) {

        // Get expected parts number
        var expected = messageParts.Max(x=>x.Total);

        // Skip incompleted messages
        if(messageParts.Count() < expected) {
            continue;
        }

        // Sort messages and compile the message
        var message = messageParts.OrderBy(x => x.Partnumber).Select(x => x.Message).Aggregate((x,y) => x + y);

        // Final message
        messages.Add(new ServerMessage{
            Messagenumber = messageParts.First().Messagenumber,
            Message = message
        });
    }

    // Final messages
}

class ServerMessage {
    public string Messagenumber {get; set;}
    public string Message {get; set;}
}

class ServerMessagePart {
    public string Messagenumber {get; set;}
    public string Message {get; set;}
    public int Partnumber {get; set;}
    public int Total {get; set;}
}

答案 4 :(得分:0)

这是我的:(更新以删除部分内容)

var messages = new Message[] {
    new Message("52e7d68d-462b-46b9-8eec-f289bcdf7b06", "BB", 2, 2),
    new Message("0529069f-a403-4eea-a955-430a10995745", "A", 1, 3),
    new Message("0529069f-a403-4eea-a955-430a10995745", "B", 2, 3),
    new Message("0529069f-a403-4eea-a955-430a10995745", "C", 3, 3),
    new Message("52e7d68d-462b-46b9-8eec-f289bcdf7b06", "AA", 1, 2),
};

    var grouped = (from m in messages
                  group m by m.messagenumber into g
                  select new
                  {
                    messagenumber = g.Key,
                    message = String.Join("", g.OrderBy(dr =>dr.partnumber)
                                               .Select(m=>m.message)),
                    count = g.Count(),
                    total = g.First().total
                  }).Where(c=>c.count == c.total);