有没有一种方法可以让我拥有一本字典,而我只需要获得在Linq中不止一次出现的那对 ? 例如在
中{1, "entries"},
{2, "images"},
{3, "views"},
{4, "images"},
{5, "results"},
{6, "images"},
{7, "entries"}
我得到了
{1, "entries"},
{2, "images"},
{6, "images"},
{7, "entries"}
答案 0 :(得分:13)
如果您只是指多次出现的值,您可以按值对键/值对进行分组,过滤掉只有一个项目的组并选择公共组键(原始组)从剩下的内容中多次出现的值:
var multiples = dictionary.GroupBy(p => p.Value)
.Where(g => g.Count() > 1)
.Select(g => g.Key);
如果您希望所有值的键/值对出现多次,则此变体将执行此操作:
var multiples = dictionary.GroupBy(p => p.Value)
.Where(g => g.Count() > 1)
.SelectMany(g => g);
唯一的区别在于最后一步,其中在仅使用一个值转出组后,所有剩余组的内容被“解包”为单个键/值对序列。
在后一种情况下,您可以通过跟进
将结果重新转换为字典(基本上过滤掉仅出现一次的值).ToDictionary(p => p.Key, p => p.Value)
最后一个例子,以查询形式:
var multiples = from pair in dictionary
group pair by pair.Value into grp
where grp.Count() > 1
from pair in grp select pair;
答案 1 :(得分:2)
var res = dict.GroupBy(x => x.Value).Where(y => y.Count() > 1);
如果你想获得一个词典:
var res = dict.GroupBy(x => x.Value)
.Where(y => y.Count() > 1)
.SelectMany(z => z)
.ToDictionary(k => k.Key, k => k.Value);
答案 2 :(得分:0)
Dictionary<int,string> d = new Dictionary<int,string>();
d.Add(1, "entries");
d.Add(2, "images");
d.Add(3, "views");
d.Add(4, "images");
d.Add(5, "results");
d.Add(6, "images");
d.Add(7, "entries");
d.GroupBy(x => x.Value)
.Where(x=>x.Count()>1)
.SelectMany(x => x)
.ToDictionary
(
x => x.Key,
x=>x.Value
);
答案 3 :(得分:0)
使用这些扩展方法,您可以获得(一点点)更快速且通用的解决方案(适用于所有IEnumarable源):
public static class Extensions
{
public static IEnumerable<TSource> Duplicates<TSource, TKey>(this IEnumerable<TSource> source, Func<TSource, TKey> selector)
{
var grouped = source.GroupBy(selector);
var moreThen1 = grouped.Where(i => i.IsMultiple());
return moreThen1.SelectMany(i => i);
}
public static bool IsMultiple<T>(this IEnumerable<T> source)
{
var enumerator = source.GetEnumerator();
return enumerator.MoveNext() && enumerator.MoveNext();
}
}
填写来源:
// Create the source
var dictionary = new Dictionary<int, string>
{
{1, "entries"},
{2, "images"},
{3, "views"},
{4, "images"},
{5, "results"},
{6, "images"},
{7, "entries"}
};
以下是3个选项(每个选项都有改进):
// More or less the same solution as other answers
var multiples1 = dictionary.GroupBy(p => p.Value)
.Where(g => g.Count() > 1)
.SelectMany(g => g);
// A little bit faster because IsMultiple does not enumerate all values
// (Count() iterates to the end, which is not needed in this case).
var multiples2 = dictionary.GroupBy(p => p.Value)
.Where(g => g.IsMultiple())
.SelectMany(g => g);
// Easy to read
var multiples3 = dictionary.Duplicates(p => p.Value);