这是一种简单的方法。有很多方法,这将包括重复的密钥作为我对您的问题的评论。如果许多键匹配相同的数据,则分组将包括副本。
// have the list of keys (groups)
var keyList = new List<string>() {"apple", "orange"};
// have the list of all the data to split
var dataToSplit = new List<string>()
{
"apple.txt",
"apple.2.tf.txt",
"orange.txt",
"orange.sd.2.txt"
};
// now split to get just as desired you select what you want for each keys
var groupedData = keyList.Select(key => dataToSplit.Where(data => data.Contains(key)).ToList()).ToList();
// groupedData is a List<List<string>>
以更“对象”的方式获取值的第二个选项是使用匿名。如果您要进行大量操作并且代码中更加“冗长”,则特别好。但如果你是新手,我不推荐这种方法,但无论如何就是这样。
// have the list of keys (groups)
var keyList = new List<string>() {"apple", "orange"};
// have the list of all the data to split
var dataToSplit = new List<string>()
{
"apple.txt",
"apple.2.tf.txt",
"orange.txt",
"orange.sd.2.txt"
};
// create the anonymous
var anonymousGroup = keyList.Select(key =>
{
return new
{
Key = key,
Data = dataToSplit.Where(data => data.Contains(key)).ToList()
}
});
// anonymousGroup is a List<A> where keeping the order you should access all data for orange like this
var orangeGroup = anonymousGroup.FirstOfDefault(o=> o.Key = "orange"); // get the anonymous
var orangeData = orangeGroup.Data; // get the List<string> for that group
第三种方法的复杂度低于 O(m*n)。诀窍是从集合中删除数据,以减少重新检查已处理项目的机会。这是来自我的代码库,它是 List 的扩展,它只是根据谓词从集合中删除项目并返回已删除的内容。
public static List<T> RemoveAndGet<T>(this List<T> list, Func<T, bool> predicate)
{
var itemsRemoved = new List<T>();
// iterate backward for performance
for (int i = list.Count - 1; i >= 0; i--)
{
// keep item pointer
var item = list[i];
// if the item match the remove predicate
if (predicate(item))
{
// add the item to the returned list
itemsRemoved.Add(item);
// remove the item from the source list
list.RemoveAt(i);
}
}
return itemsRemoved;
}
现在有了这个扩展,当你有一个列表时,你可以像这样轻松地使用它:
// have the list of keys (groups)
var keyList = new List<string>() {"apple", "orange"};
// have the list of all the data to split
var dataToSplit = new List<string>()
{
"apple.txt",
"apple.2.tf.txt",
"orange.txt",
"orange.sd.2.txt"
};
// now split to get just as desired you select what you want for each keys
var groupedData = keyList.Select(key => dataToSplit.RemoveAndGet(data => data.Contains(key))).ToList();
在这种情况下,由于两个集合中的顺序,第一个键是 apple,因此它将迭代 dataToSplit 中的 4 个项目并仅保留 2 个并将 dataToSplit 集合减少到 2 个项目仅是具有orange 在其中。在第二个键上,它将仅迭代 2 个项目,这将使其在这种情况下更快。通常,此方法将与我提供的前 2 个方法一样快或更快,同时清晰且仍然使用 linq。