分层父子关系数据中仅父级上的C#LINQ Orderby
我在LINQ有一个有趣的问题,我不知道如何解决它。下面是我的数据 我有一个发送对象列表(分层父子关系数据中仅父级上的C#LINQ Orderby,c#,linq,C#,Linq,我在LINQ有一个有趣的问题,我不知道如何解决它。下面是我的数据 我有一个发送对象列表(list),其中发送对象具有以下属性 public class Send { public string messageName { get; set; } public string Port { get; set; } public string Type { get; set; } } 其中端口可以是PortA、PortB等。类型只能是“接收”或“发送”,
list
),其中发送对象具有以下属性
public class Send
{
public string messageName { get; set; }
public string Port { get; set; }
public string Type { get; set; }
}
其中端口可以是PortA、PortB
等。类型只能是“接收”
或“发送”
,并且可以是messageName
0_firstmessage
1_secondmessage
2_thirdmessage
messageName始终在开头0,1,2…处有一个标识符
我当前的列表包含如下数据。数据中需要注意的几点
MESSAGENAME, PORT , TYPE
- 0_message , PortA , receive
- 1_message , PortA , transmit
- 3_message , PortA , transmit
- 7_message , PortA , transmit
- 8_message , PortA , receive
- 9_message , PortA , transmit
- 2_message , PortB , receive
- 4_message , PortB , receive
- 5_message , PortB , transmit
- 6_message , PortB , transmit
- 10_message, PortB , receive
- 11_message , PortB , transmit
我的最终输出应该是这样的
MESSAGENAME, PORT , TYPE
- 0_message , PortA , receive
- 1_message , PortA , transmit
- 3_message , PortA , transmit
- 7_message , PortA , transmit
- 2_message , PortB , receive
- 4_message , PortB , receive
- 5_message , PortB , transmit
- 6_message , PortB , transmit
- 8_message , PortA , receive
- 9_message , PortA , transmit
- 10_message, PortB , receive
- 11_message , PortB , transmit
我只想根据“接收”类型的消息的消息名称进行订购。子“传输”消息应保持完整
我在网上搜索了很多,但我不知道如何编写这个LINQ查询
这里有一个例子:你可以在这里玩。
请尝试下面的代码
public class Send : IComparable<Send>
{
public string messageName { get; set; }
public string Port { get; set; }
public string Type { get; set; }
public int CompareTo(Send other)
{
int results = 0;
if (this.messageName != other.messageName)
{
results = this.messageName.CompareTo(other.messageName);
}
else
{
if (this.Port != other.Port)
{
results = this.Port.CompareTo(other.Port);
}
else
{
results = this.Type.CompareTo(other.Type);
}
}
return results;
}
}
公共类发送:i可比较
{
公共字符串messageName{get;set;}
公共字符串端口{get;set;}
公共字符串类型{get;set;}
公共整数比较(发送其他)
{
int结果=0;
if(this.messageName!=其他.messageName)
{
结果=this.messageName.CompareTo(其他.messageName);
}
其他的
{
if(this.Port!=其他.Port)
{
结果=此.Port.CompareTo(其他.Port);
}
其他的
{
结果=此.Type.CompareTo(其他.Type);
}
}
返回结果;
}
}
我有一个解决方案,假设您首先接收receive
,然后是transmit
类型的消息
int gid=0;
var results = messages.Select(m => new
{ // Rank each message
m.Type.Equals("Receive", StringComparison.InvariantCultureIgnoreCase ) ? ++gid: gid,
message=m
})
.GroupBy(g=>g.groupid) // Group them on Rank
.OrderBy(g=>int.Parse(g.First().message.messageName.Split('_')[0])) // apply Sort
.SelectMany(c=>c.Select(x=>x.message)) // flatten structure .
.ToList() ;
检查工作状态我希望此LINQ可以帮助您:
var a = mylist.OrderBy(x => x.MESSAGENAME).Where(y => y.TYPE == "receive")
.Concat(mylist.Where(z => z.TYPE!= "receive"));
因此,您将获得IEnumerable,其中第一个按消息类型发送,第二个按消息类型发送,其余的发送都是无序的。我还有一个建议给您。您可以添加一个字典,并将您的列表放在key-will-yoursend with message type=“receive”的位置,然后您可以简单地按键订购字典。检查此代码:
List<Send> messages = new List<Send>();
messages.Add(new Send() {messageName ="0_message" , Port = "PortA", Type="Receive" });
messages.Add(new Send() {messageName ="1_message" , Port = "PortA", Type="transmit" });
messages.Add(new Send() {messageName ="3_message" , Port = "PortA", Type="transmit" });
messages.Add(new Send() {messageName ="7_message" , Port = "PortA", Type="transmit" });
messages.Add(new Send() {messageName ="8_message" , Port = "PortA", Type="Receive" });
messages.Add(new Send() {messageName ="9_message" , Port = "PortA", Type="transmit" });
messages.Add(new Send() {messageName ="2_message" , Port = "PortB", Type="Receive" });
messages.Add(new Send() {messageName ="4_message" , Port = "PortB", Type="Receive" });
messages.Add(new Send() {messageName ="5_message" , Port = "PortB", Type="transmit" });
messages.Add(new Send() {messageName ="6_message" , Port = "PortB", Type="transmit" });
messages.Add(new Send() {messageName ="10_message" , Port = "PortB", Type="Receive" });
messages.Add(new Send() {messageName ="11_message" , Port = "PortB", Type="transmit" });
Dictionary<Send, List<Send>> myDict = new Dictionary<Send, List<Send>>();
List<Send> mylist2 = new List<Send>();
Send messagename = new Send();
int i = 0;
foreach (Send s in messages)
{
if (s.Type == "Receive" || s.Type == "receive")
{
if (i != 0)
{
myDict.Add(messagename, mylist2);
}
messagename = s;
mylist2 = new List<Send>();
}
else
{
mylist2.Add(s);
}
if(i== messages.Count()-1)
{
myDict.Add(messagename, mylist2);
}
i++;
}
var q = myDict.OrderBy(x => int.Parse(x.Key.messageName.Split('_')[0]));
List messages=newlist();
添加(newsend(){messageName=“0_message”,Port=“PortA”,Type=“Receive”});
添加(newsend(){messageName=“1_message”,Port=“PortA”,Type=“transmit”});
添加(newsend(){messageName=“3_message”,Port=“PortA”,Type=“transmit”});
添加(newsend(){messageName=“7_message”,Port=“PortA”,Type=“transmit”});
添加(newsend(){messageName=“8_message”,Port=“PortA”,Type=“Receive”});
添加(newsend(){messageName=“9_message”,Port=“PortA”,Type=“transmit”});
添加(newsend(){messageName=“2_message”,Port=“PortB”,Type=“Receive”});
添加(newsend(){messageName=“4_message”,Port=“PortB”,Type=“Receive”});
添加(newsend(){messageName=“5_message”,Port=“PortB”,Type=“transmit”});
添加(newsend(){messageName=“6_message”,Port=“PortB”,Type=“transmit”});
添加(newsend(){messageName=“10_message”,Port=“PortB”,Type=“Receive”});
添加(newsend(){messageName=“11_message”,Port=“PortB”,Type=“transmit”});
Dictionary myDict=新字典();
List mylist2=新列表();
Send messagename=new Send();
int i=0;
foreach(在消息中发送消息)
{
如果(s.Type==“接收”| | s.Type==“接收”)
{
如果(i!=0)
{
myDict.Add(messagename,mylist2);
}
messagename=s;
mylist2=新列表();
}
其他的
{
mylist2.添加(s);
}
if(i==messages.Count()-1)
{
myDict.Add(messagename,mylist2);
}
i++;
}
var q=myDict.OrderBy(x=>int.Parse(x.Key.messageName.Split(“”“)[0]);
如果需要,可以将字典转换回列表:
List<Send> newlist = new List<Send>();
foreach (KeyValuePair<Send, List<Send>> k in q)
{
newlist.Add(k.Key);
foreach (Send s in k.Value)
{
newlist.Add(s);
}
}
List newlist=newlist();
foreach(q中的KeyValuePair k)
{
newlist.Add(k.Key);
foreach(以k值发送s)
{
新列表。添加(s);
}
}
向类添加属性公共发送父对象{get;set;}
(可能还有反向子对象集合)。确定所有孩子的父母。然后,在没有父对象的情况下,您应该能够简单地按messageName
排序。对于每个家长,然后打印孩子。查看我的答案,代码将不起作用。我认为您需要将发送消息作为接收消息的子消息,这样当您对发送消息进行排序时,将保留同一接收消息。我不理解这一点。这与我的问题有什么关系。请添加一些说明。需要使用IComparable进行自定义比较。OrderBy将使用类的CompareTo()方法。因此,您可以只使用OrderBy,CompareTo()方法将进行比较。它无法正常工作。我已经用我在问题描述中提到的完整数据更新了您的示例。正如您在输出中所看到的,8_message应该比10_messageAhh先出现。。我明白了,让我来修正。修正了,现在检查。谢谢你修改你的例子。但是您的查询以原始格式输出数据。我想要最终输出中的数据(如问题中提到的)。我更新了fiddler,因为您的数据中有“接收”而不是“接收”。解决方案