所以我有几个Tag类型的列表。 Tag有几个属性:.Epc,.AntennaPortNumber和.LastTimeSeen。我想从主列表中取出所有标签,并将它们分成5个较小的列表,但只保留每个.Epc的一个副本,它必须是最新的.LastTimeSeen。我不确定从哪里开始。我以为我必须要用.GroupBy嵌套几次?现在,代码分为两个主要部分:我将新标记添加到它们所属的列表中,以及删除500ms内未见过的标记。我试图阻止使用.Contains将重复标记添加到5个子列表中,但由于它们具有不同的LastTimeSeen属性,因此没有达到预期的效果。
感谢任何人可能提供的任何指导!
List<Tag> tags = new List<Tag>();
List<Tag> listMed1 = new List<Tag>();
List<Tag> listMed2 = new List<Tag>();
List<Tag> listMed3 = new List<Tag>();
List<Tag> listMed4 = new List<Tag>();
List<Tag> listMed5 = new List<Tag>();
void OnTagsReported(ImpinjReader sender, TagReport report)
{
// This event handler is called asynchronously
// when tag reports are available.
// Loop through each tag in the report
// and print the data.
//List<Tag> tags = new List<Tag>();
foreach (Tag tag in report)
{
ushort AntennaNum = tag.AntennaPortNumber;
Impinj.OctaneSdk.TagData first = tag.Epc;
string epcCheck = first.ToString().ToUpper();
Impinj.OctaneSdk.ImpinjTimestamp tim = tag.LastSeenTime;
if (epcCheck.IndexOf("A") != -1)
{
if (listMed1.Contains(tag) == false)
{
listMed1.Add(tag);
System. Diagnostics.Debug.WriteLine(epcCheck);
System.Diagnostics.Debug.WriteLine(tim);
}
}
else if (epcCheck.IndexOf("B") != -1)
{
if (listMed2.Contains(tag) == false)
{
listMed2.Add(tag);
}
}
else if (epcCheck.IndexOf("C") != -1)
{
if (listMed3.Contains(tag) == false)
{
listMed3.Add(tag);
}
}
else if (epcCheck.IndexOf("D") != -1)
{
if (listMed1.Contains(tag) == false)
{
listMed4.Add(tag);
}
}
else if (epcCheck.IndexOf("E") != -1)
{
if (listMed5.Contains(tag) == false)
{
listMed5.Add(tag);
}
}
int Med1num = listMed1.Count();
int Med2num = listMed2.Count();
int Med3num = listMed3.Count();
int Med4num = listMed4.Count();
int Med5num = listMed5.Count();
for (int loopr = 0; loopr < Med1num; loopr++)
{
Impinj.OctaneSdk.ImpinjTimestamp second = listMed1[loopr].LastSeenTime;
string milisecondsUTC = second.ToString();
long lastseen = Convert.ToInt64(milisecondsUTC);
TimeSpan t = DateTime.UtcNow - new DateTime(1970, 1, 1);
long secondsSinceEpoch = (long)t.TotalMilliseconds;
if (secondsSinceEpoch - lastseen > 500 )
{
listMed1.RemoveAt(loopr);
loopr = -1;
}
}
for (int loopr = 0; loopr < Med2num; loopr++)
{
Impinj.OctaneSdk.ImpinjTimestamp second = listMed2[loopr].LastSeenTime;
string milisecondsUTC = second.ToString();
long lastseen = Convert.ToInt64(milisecondsUTC);
TimeSpan t = DateTime.UtcNow - new DateTime(1970, 1, 1);
long secondsSinceEpoch = (long)t.TotalMilliseconds;
if (secondsSinceEpoch - lastseen > 500)
{
listMed2.RemoveAt(loopr);
loopr = -1;
}
}
for (int loopr = 0; loopr < Med3num; loopr++)
{
Impinj.OctaneSdk.ImpinjTimestamp second = listMed3[loopr].LastSeenTime;
string milisecondsUTC = second.ToString();
long lastseen = Convert.ToInt64(milisecondsUTC);
TimeSpan t = DateTime.UtcNow - new DateTime(1970, 1, 1);
long secondsSinceEpoch = (long)t.TotalMilliseconds;
if (secondsSinceEpoch - lastseen > 500)
{
listMed3.RemoveAt(loopr);
loopr = -1;
}
}
for (int loopr = 0; loopr < Med4num; loopr++)
{
Impinj.OctaneSdk.ImpinjTimestamp second = listMed4[loopr].LastSeenTime;
string milisecondsUTC = second.ToString();
long lastseen = Convert.ToInt64(milisecondsUTC);
TimeSpan t = DateTime.UtcNow - new DateTime(1970, 1, 1);
long secondsSinceEpoch = (long)t.TotalMilliseconds;
if (secondsSinceEpoch - lastseen > 500)
{
listMed4.RemoveAt(loopr);
loopr = -1;
}
}
for (int loopr = 0; loopr < Med5num; loopr++)
{
Impinj.OctaneSdk.ImpinjTimestamp second = listMed5[loopr].LastSeenTime;
string milisecondsUTC = second.ToString();
long lastseen = Convert.ToInt64(milisecondsUTC);
TimeSpan t = DateTime.UtcNow - new DateTime(1970, 1, 1);
long secondsSinceEpoch = (long)t.TotalMilliseconds;
if (secondsSinceEpoch - lastseen > 500)
{
listMed5.RemoveAt(loopr);
loopr = -1;
}
}
Med1num = listMed1.Count();
Med2num = listMed2.Count();
Med3num = listMed3.Count();
Med4num = listMed4.Count();
Med5num = listMed5.Count();
SetText(Med1num, Med2num, Med3num, Med4num, Med5num);
}
}
答案 0 :(得分:0)
像这样:
/// <summary>The group</summary>
enum eGroup : byte
{
A, B, C, D, E
};
static IEnumerable<eGroup> allGroups()
{
return Enum.GetValues( typeof( eGroup ) ).Cast<eGroup>();
}
/// <summary>Classify tag to the group, returns null if failed.</summary>
static eGroup? classify( Tag tag )
{
string str = tag.Epc.ToString().ToUpper();
foreach( eGroup e in allGroups() )
if( str.Contains( e.ToString ) )
return e;
return null;
}
/// <summary>Add tag to list unless it's already there.</summary>
static void addToList( List<Tag> list, Tag t )
{
int ind = list.IndexOf( t );
if( ind < 0 )
list.Add( t ); // Not on the list
else if( list[ ind ].LastSeenTime.Utc < t.LastSeenTime.Utc )
list[ ind ] = t; // Only replace if newer then the existing one
}
/// <summary>The collection to hold all that groups.</summary>
readonly Dictionary<eGroup, List<Tag>> med = allGroups().ToDictionary( e => e, e => new List<Tag>() );
/// <summary>True if that tag is too old.</summary>
static bool isTooOld( Tag t )
{
ImpinjTimestamp ts = t.LastSeenTime;
DateTime utc = new DateTime( 1970, 1, 1, 0, 0, 0, DateTimeKind.Utc ).AddTicks( (long)ts.Utc * 10L );
return ( DateTime.UtcNow - utc ).TotalMilliseconds > 500;
}
void OnTagsReported( ImpinjReader sender, TagReport report )
{
// Classify and add to the correct group
foreach( Tag tag in report )
{
eGroup? group = classify( tag );
if( !group.HasValue ) continue;
addToList( med[ group.Value ], tag );
}
// Remove too old tags
foreach( var list in med.Values )
list.RemoveAll( isTooOld );
// Show counts
int[] c = allGroups().Select( e => med[ e ].Count ).ToArray();
SetText( c[ 0 ], c[ 1 ], c[ 2 ], c[ 3 ], c[ 4 ] );
}
答案 1 :(得分:0)
在我看来,这就是你可能需要的全部内容:
--junitxml
void OnTagsReported(ImpinjReader sender, TagReport report)
{
tags.RemoveAll(tag => report.Select(r => r.Epc).Contains(tag.Epc));
tags.AddRange(report);
tags.RemoveAll(tag =>
{
Impinj.OctaneSdk.ImpinjTimestamp second = tag.LastSeenTime;
string milisecondsUTC = second.ToString();
long lastseen = Convert.ToInt64(milisecondsUTC);
TimeSpan t = DateTime.UtcNow - new DateTime(1970, 1, 1);
long secondsSinceEpoch = (long)t.TotalMilliseconds;
return secondsSinceEpoch - lastseen > 5000;
});
var counts =
new[] { "A", "B", "C", "D", "E", }
.Select(c =>
tags
.Where(tag => tag.Epc.ToString().IndexOf(c) != -1)
.Count())
.ToArray();
SetText(counts[0], counts[1], counts[2], counts[3], counts[4]);
}
定义可能是引起悲伤的唯一因素,但如果这种基本的方式不能为您提供所需的结果,我可以使其发挥作用。
确保代码顶部有counts
。
这是我为测试目的而创建的对象模型。它允许OP的代码和我的代码进行编译。
using System.Linq;
答案 2 :(得分:0)
如果要防止重复,则应考虑设置。根据您的需要,TreeSet可用于排序数据,在这种情况下,您必须确保Tag实现IComparable。否则HashSet应该很合适 如果您想继续使用列表,必须覆盖标记上的等于方法。鉴于您的代码,我们无法看到Tag的结构,但您使用List.Contains方法。你应该在不考虑LastTimeSeen的情况下实现Equals 您也不应该以这种方式使用IndexOf,因为它会掩盖代码,您应该能够用String.Contains替换它。使用Linq作为Enigmativity建议也可以大大清理你的代码。
如果您无权访问该库的源代码,则应在所选集合上创建辅助方法或扩展方法,以检查其是否相等。