我想要做的是在searchValues列表中搜索重复的itemId,当我找到它们时,将单个字符串值放入字符串值数组中。
SearchValue对象:
public class SearchValue<TItemId>
{
public TItemId ItemId { get; set; }
public string Value { get; set; }
public string[] Values { get; set; }
}
init之后的测试搜索值如下所示:
searchValues[0]
.ItemId == 16
.Value == "2"
searchValues[1]
.ItemId == 16
.Value == "3"
searchValues[2]
.ItemId == 15
.Value == "6"
searchValues[3]
.ItemId == 15
.Value == "3"
searchValues[4]
.ItemId == 5
.Value == "Vertonghen"
我希望我的最终结果如下:
searchValues[0]
.ItemId == 16
.Values == "2,3"
searchValues[1]
.ItemId == 15
.Values == "6,3"
searchValues[2]
.ItemId == 5
.Value == "Vertonghen"
我真的想用LINQ做这件事。我已设法创建另一个SearchValue列表:
List<SearchValue<Byte>> duplicateSearchItems = (from x in searchValues
group x by x.ItemId into grps
orderby grps.Key
where grps.Count() > 1
select grps).SelectMany(group => group).ToList();
...但是将值放入values数组会给我带来麻烦。理想情况下,如果LINQ可以返回一个包含重复记录的单个列表,这些重复记录被转换为数组,其中非重复项完好无损。可能是某种嵌套查询?我很难过。有什么想法吗?
提前致谢!
答案 0 :(得分:0)
为什么不使用词典
Dictionary<int,string> d = new Dictionary<int,string>();
foreach(var x in searchValues)
{
if(d.ContainsKey(x.ItemId))
d[x.ItemId] = string.Format("{0},{1}",d[x.ItemId],x.Value);
else
d.Add(x.ItemId,x.Value);
}
最后简单地通过词典重复
foreach(var entry in d)
{
ConsoleWriteline(entry.Key+" : "+entry.Value);
}
答案 1 :(得分:0)
单独使用Linq不能用于修改原始列表或修改列表中的项目。但是,您可以执行此操作以创建新列表:
List<SearchValue<Byte>> results =
(from x in searchValues
group x by x.ItemId into g
select new SearchValue<Byte>()
{
ItemId = g.Key,
Value = g.Value.First().Value,
Values = g.Value.Select(i => i.Value).ToArray(),
}
.ToList();
或者用流利的语法:
List<SearchValue<Byte>> results = searchValues
.GroupBy(x => x.ItemId)
.Select(g => new SearchValue<Byte>()
{
ItemId = g.Key,
Value = g.Value.First().Value,
Values = g.Value.Select(i => i.Value).ToArray(),
})
.ToList();
但是,根据您的具体情况,ILookup
可能更适合您:
var results = searchValues.ToLookup(x => x.ItemId, x => x.Value);
Console.Write(String.Join(", ", results[16])); // 2, 16
答案 2 :(得分:0)
我认为LINQ不会为您提供最佳解决方案。与尼古拉相似,我会使用字典。如果您未与SearchValue数据类型结合,则可以避免将数据推回到您的类型中的第二个循环。字典&gt;会在这里工作。
var searchValues = new List<SearchValue<int>>();
var distinctItemIds = new Dictionary<int, List<string>>();
foreach (var item in searchValues)
{
if (!distinctItemIds.ContainsKey(item.ItemId))
{
distinctItemIds.Add(item.ItemId, new List<string>());
}
// Add the value
distinctItemIds[item.ItemId].Add(item.Value);
}
// Put values back into your data object
var finishedValues = new List<SearchValue<int>>();
foreach (var keyValuePair in distinctItemIds)
{
finishedValues.Add(new SearchValue<int>()
{
ItemId = keyValuePair.Key,
Values = keyValuePair.Value.ToArray()
});
}
答案 3 :(得分:0)
我设法使用LINQ解决了这个问题。
// Get a new list of unique items to add our duplicated items to
List<SearchValue<Byte>> finalSearchItems = (from x in searchValues
group x by x.ItemId into grps
orderby grps.Key
where grps.Count() == 1
select grps).SelectMany(group => group).ToList();
byte[] duplicateIds = (from x in searchValues
group x by x.ItemId into grps
where grps.Count() > 1
select grps.Key).ToArray();
// Smash the string 'Value' into 'Values[]'
foreach (byte id in duplicateIds)
{
SearchValue<Byte> val = new SearchValue<byte>();
val.ItemId = id;
// Smash
val.Values = (from s in searchValues
where s.ItemId == id
select s.Value).ToArray();
finalSearchItems.Add(val);
}