簡體   English   中英

連接來自json數組的自定義對象的字符串屬性

[英]Concatenate string property of a custom object from json array

這是問題的簡要說明。 從服務器我得到的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語句優雅地完成此操作嗎?

感謝您的任何建議。

這應該做您想要的:

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. PartNumber對每個分組的所有消息進行排序,以確保一切PartNumber正確的順序進行
  4. 瀏覽所有分組並選擇所有消息
  5. 匯總消息

結果是串聯字符串的枚舉。

試試這個代碼:

var input = new List<FullMessage>();

var result = input.GroupBy(m => new { m.MessageNumber, m.Total })
    .Where(g => g.Count() == g.Key.Total)
    .Select(g => new FullMessage
    {
        MessageNumber = g.Key.MessageNumber,
        Message = g.OrderBy(i => i.PartNumber).Aggregate("", (c, n) => c + n.Message)
    });

假設訊息看起來像

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. 使用Aggregate在新的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;
    }));

下面的示例代碼:

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;}
}

這是我的:(已更新以刪除部分內容)

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);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM