c# - una - Cómo contar duplicados en la lista con LINQ
contar valores repetidos en un array c# (5)
Las otras soluciones usan GroupBy
. GroupBy
es lento (contiene todos los elementos en la memoria) así que escribí mi propio método CountBy
:
public static Dictionary<TKey,int> CountBy<TSource,TKey>(this IEnumerable<TSource> source, Func<TSource,TKey> keySelector)
{
var countsByKey = new Dictionary<TKey,int>();
foreach(var x in source)
{
var key = keySelector(x);
if (!countsByKey.ContainsKey(key))
countsByKey[key] = 0;
countsByKey[key] += 1;
}
return countsByKey;
}
Tengo una lista de artículos
- John ID
- Matt ID
- John ID
- ID de Scott
- Matt ID
- John ID
- Identificación de Lucas
Quiero incluirlos nuevamente en una lista como tal, lo que también significa que quiero ordenar por el mayor número de duplicados.
- John ID 3
- Matt ID 2
- Scott ID 1
- ID de Lucas 1
Déjame saber cómo puedo hacer esto con LINQ y C #.
Gracias a todos
EDITAR 2 mostrando código:
List<game> inventory = new List<game>();
drinkingforDataContext db = new drinkingforDataContext();
foreach (string item in tbTitle.Text.Split('' ''))
{
List<game> getItems = (from dfg in db.drinkingfor_Games
where dfg.game_Name.Contains(tbTitle.Text)
select new game
{
gameName = dfg.game_Name,
gameID = Boomers.Utilities.Guids.Encoder.EncodeURLs(dfg.uid)
}).ToList<game>();
for (int i = 0; i < getItems.Count(); i++)
{
inventory.Add(getItems[i]);
}
}
var items = (from xx in inventory
group xx by xx into g
let count = g.Count()
orderby count descending
select new
{
Count = count,
gameName = g.Key.gameName,
gameID = g.Key.gameID
});
lvRelatedGames.DataSource = items;
lvRelatedGames.DataBind();
Esta consulta muestra estos resultados:
- 1 hola mundo veces
- 1 hola mundo veces
- 1 Hola mundo.
- 1 hola mundo veces
- 1 hola mundo veces
- 1 hola mundo veces
- 1 Hola mundo.
- 1 hola mundo veces
Me da la cuenta y el nombre, pero no me da la identificación del juego ...
Debería mostrar:
- 6 hola mundo veces 234234
- 2 Hola mundo. 23432432
Puede usar "group by" + "orderby". Ver LINQ 101 para más detalles
var list = new List<string> {"a", "b", "a", "c", "a", "b"};
var q = from x in list
group x by x into g
let count = g.Count()
orderby count descending
select new {Value = g.Key, Count = count};
foreach (var x in q)
{
Console.WriteLine("Value: " + x.Value + " Count: " + x.Count);
}
En respuesta a esta publicación (ahora eliminada):
Si tiene una lista de algunos objetos personalizados, entonces necesita usar un comparador o grupo personalizado por propiedad específica.
Además, la consulta no puede mostrar el resultado. Muéstranos el código completo para obtener una mejor ayuda.
En función de su última actualización:
Usted tiene esta línea de código:
group xx by xx into g
Como xx es un sistema de objeto personalizado, no sabe cómo comparar un elemento con otro. Como ya escribí, debe guiar el compilador y proporcionar alguna propiedad que se utilizará en comparación de objetos o proporcionar comparador personalizado. Aquí hay un ejemplo:
Tenga en cuenta que utilizo Foo.Name como clave, es decir, los objetos se agruparán en función del valor de la propiedad Name .
Hay un inconveniente: usted trata 2 objetos para duplicar en función de sus nombres, pero ¿qué pasa con Id? En mi ejemplo, simplemente tomo Id del primer objeto en un grupo. Si sus objetos tienen diferentes ID, puede ser un problema.
//Using extension methods
var q = list.GroupBy(x => x.Name)
.Select(x => new {Count = x.Count(),
Name = x.Key,
ID = x.First().ID})
.OrderByDescending(x => x.Count);
//Using LINQ
var q = from x in list
group x by x.Name into g
let count = g.Count()
orderby count descending
select new {Name = g.Key, Count = count, ID = g.First().ID};
foreach (var x in q)
{
Console.WriteLine("Count: " + x.Count + " Name: " + x.Name + " ID: " + x.ID);
}
También puedes hacer Diccionario:
var list = new List<string> { "a", "b", "a", "c", "a", "b" };
var result = list.GroupBy(x => x)
.ToDictionary(y=>y.Key, y=>y.Count())
.OrderByDescending(z => z.Value);
foreach (var x in result)
{
Console.WriteLine("Value: " + x.Key + " Count: " + x.Value);
}
Versión un poco más corta usando la cadena de métodos:
var list = new List<string> {"a", "b", "a", "c", "a", "b"};
var q = list.GroupBy(x => x)
.Select(g => new {Value = g.Key, Count = g.Count()})
.OrderByDescending(x=>x.Count);
foreach (var x in q)
{
Console.WriteLine("Value: " + x.Value + " Count: " + x.Count);
}
Aquí está el programa completo por favor verifique esto
static void Main(string[] args)
{
List<string> li = new List<string>();
li.Add("Ram");
li.Add("shyam");
li.Add("Ram");
li.Add("Kumar");
li.Add("Kumar");
var x = from obj in li group obj by obj into g select new { Name = g.Key, Duplicatecount = g.Count() };
foreach(var m in x)
{
Console.WriteLine(m.Name + "--" + m.Duplicatecount);
}
Console.ReadLine();
}