web-dev-qa-db-fra.com

Linq select to nouvel objet

J'ai une requête linq 

var x = (from t in types select t).GroupBy(g =>g.Type)

qui regroupe des objets en fonction de leur type, par conséquent, je souhaite créer un nouvel objet contenant tous les objets groupés et leur nombre. Quelque chose comme ça:

type1, 30    
type2, 43    
type3, 72

pour être plus clair: les résultats de regroupement doivent être dans un objet et non pas un objet par type d'élément

26
Jeff

Lire: 101 Exemples LINQ dans lequel LINQ - Opérateurs de regroupement à partir du site Microsoft MSDN 

var x = from t in types  group t by t.Type
         into grp    
         select new { type = grp.key, count = grp.Count() };

forsingle object utilise stringbuilder et l’ajoute qui le fera ou le convertira sous forme de dictionnaire 

    // fordictionary 
  var x = (from t in types  group t by t.Type
     into grp    
     select new { type = grp.key, count = grp.Count() })
   .ToDictionary( t => t.type, t => t.count); 

   //for stringbuilder not sure for this 
  var x = from t in types  group t by t.Type
         into grp    
         select new { type = grp.key, count = grp.Count() };
  StringBuilder MyStringBuilder = new StringBuilder();

  foreach (var res in x)
  {
       //: is separator between to object
       MyStringBuilder.Append(result.Type +" , "+ result.Count + " : ");
  }
  Console.WriteLine(MyStringBuilder.ToString());   
33
Pranay Rana

Tous les objets groupés, ou tous les types? Il semble que vous souhaitiez simplement:

var query = types.GroupBy(t => t.Type)
                 .Select(g => new { Type = g.Key, Count = g.Count() });

foreach (var result in query)
{
    Console.WriteLine("{0}, {1}", result.Type, result.Count);
}

EDIT: Si vous voulez dans un dictionnaire, vous pouvez simplement utiliser:

var query = types.GroupBy(t => t.Type)
                 .ToDictionary(g => g.Key, g => g.Count());

Il n'est pas nécessaire de sélectionner des paires et then construire le dictionnaire.

25
Jon Skeet

Les réponses ici m'ont rapproché, mais en 2016, j'ai pu écrire le LINQ suivant:

List<ObjectType> objectList = similarTypeList.Select(o =>
    new ObjectType
    {
        PropertyOne = o.PropertyOne,
        PropertyTwo = o.PropertyTwo,
        PropertyThree = o.PropertyThree
    }).ToList();
19
dckuehn
var x = from t in types
        group t by t.Type into grouped
        select new { type = grouped.Key,
                     count = grouped.Count() };
3
daryal

Si vous voulez pouvoir effectuer une recherche sur chaque type pour obtenir sa fréquence, vous devez transformer l'énumération en dictionnaire.

var types = new[] {typeof(string), typeof(string), typeof(int)};
var x = types
        .GroupBy(type => type)
        .ToDictionary(g => g.Key, g => g.Count());
foreach (var kvp in x) {
    Console.WriteLine("Type {0}, Count {1}", kvp.Key, kvp.Value);
}
Console.WriteLine("string has a count of {0}", x[typeof(string)]);
1
Steve

C'est un excellent article sur la syntaxe nécessaire pour créer de nouveaux objets à partir d'une requête LINQ.

Mais, si les assignations à renseigner dans les champs de l'objet sont plus que de simples assignations, par exemple, l'analyse de chaînes en entiers, et que l'une d'entre elles échoue, il n'est pas possible de la déboguer. Vous ne pouvez pas créer de point d'arrêt sur les affectations individuelles.

Et si vous déplacez toutes les affectations vers un sous-programme, retournez un nouvel objet et tentez de définir un point d'arrêt dans cette routine, vous pouvez définir un point d'arrêt dans cette routine, mais ce point d'arrêt ne sera jamais déclenché.

Donc au lieu de:

var query2 = from c in doc.Descendants("SuggestionItem")
                select new SuggestionItem
                       { Phrase = c.Element("Phrase").Value
                         Blocked = bool.Parse(c.Element("Blocked").Value),
                         SeenCount = int.Parse(c.Element("SeenCount").Value)
                       };

Ou

var query2 = from c in doc.Descendants("SuggestionItem")
                         select new SuggestionItem(c);

J'ai plutôt fait ceci:

List<SuggestionItem> retList = new List<SuggestionItem>();

var query = from c in doc.Descendants("SuggestionItem") select c;

foreach (XElement item in query)
{
    SuggestionItem anItem = new SuggestionItem(item);
    retList.Add(anItem);
}

Cela m'a permis de déboguer facilement et de déterminer quelle affectation échouait. Dans ce cas, il manquait dans le XElement un champ analysé dans le champ SuggestionItem.

J'ai rencontré ces pièges avec Visual Studio 2017 en écrivant des tests unitaires pour une nouvelle routine de bibliothèque.

0
Garnet R. Chaney