Je ne suis pas tellement dans C # et .NET . J'ai le problème suivant.
Dans mon code, j'ai quelque chose comme ceci:
public class UOR { private string unitaOperativaResponsabile; public string UnitaOperativaResponsabile { get { return unitaOperativaResponsabile; } set { unitaOperativaResponsabile = value; } } private string areaOrganizzativaOmogenea; public string AreaOrganizzativaOmogenea { get { return areaOrganizzativaOmogenea; } set { areaOrganizzativaOmogenea = value; } } private string siglaAOO; public string SiglaAOO { get { return siglaAOO; } set { siglaAOO = value; } } private string siglaUOR; public string SiglaUOR { get { return siglaUOR; } set { siglaUOR = value; } } private int idUor; public int IdUor { get { return idUor; } set { idUor = value; } } private bool attiva; public bool Attiva { get { return attiva; } set { attiva = value; } } private int alias; public int Alias { get { return alias; } set { alias = value; } } public override int GetHashCode() { // Get the hash code for the Textual field if it is not null. int hashTextual = siglaAOO == null ? 0 : siglaAOO.GetHashCode(); // Get the hash code for the Digital field. int hashDigital = idUor.GetHashCode(); // Calculate the hash code for the object. return hashDigital ^ hashTextual; } public override bool Equals(System.Object obj) { // If parameter is null return false. if (obj == null) { return false; } // If parameter cannot be cast to Point return false. UOR p = obj as UOR; if ((System.Object)p == null) { return false; } // Return true if the fields match: return (idUor == p.idUor) && (siglaAOO.Equals(p.siglaAOO)); } public bool Equals(UOR p) { // If parameter is null return false: if ((object)p == null) { return false; } // Return true if the fields match: return (idUor == p.idUor) && (siglaAOO.Equals(p.siglaAOO)); } }
où visibUtils.Uors est une liste de Objet UOR .
Comme vous pouvez le voir, je suis en train d'itérer sur une liste d'identifiants ( visibilitaPostRidistribuzioni ). Pour chaque ID, je récupère un objet UOR uor et je l'ajoute à la liste visibUtils.Uors .
Ce dont j'ai besoin, c'est d'une manière intelligente pour vérifier si cet objet uor existe dans la liste visibUtils.Uors avant de l'insérer pour éviter la duplication.
2 objets UOR sont le même objet s'ils ont les mêmes valeurs pour ces 2 champs: SiglaAOO et SiglaUOR
Un L'objet UOR est une classe modèle comme celle-ci:
UOR uor; foreach (int idUor in visibilitaPostRidistribuzioni) { uor = UorSQL.GetUorFromId(siglaAOO, idUor, dbConfig); visibUtils.Uors.Add(uor); }
Je sais que je peux itérer sur la liste visibUtils.Uors et vérifiez si dans cette liste existe un objet ayant la même valeur de champs SiglaAOO et SiglaUOR si l'objet courant que je dois insérer.
Mais. ..existe d'une manière plus intelligente? (peut-être quelque chose lié à l'expression lambda)
3 Réponses :
Modifiez ceci comme suit:
foreach (int idUor in visibilitaPostRidistribuzioni) { var uor = UorSQL.GetUorFromId(siglaAOO, idUor, dbConfig); if(!visibUtils.Uors.Any(a => a.Equals(uor)) { visibUtils.Uors.Add(uor); } }
C'est uor
qui ne doit pas être présent, pas idUor
.
Réponse modifiée pour refléter cela, utilisant désormais les égales déjà implémentées
Comme vous avez défini GetHashCode
et Equals
, il est préférable d'utiliser HashSet
plutôt que List
HashSet
vérifiera l'existence avec une complexité O (1)
, tandis que List
- avec O (n)
. var interimSet = new HashSet<UOR>();
foreach (int idUor in visibilitaPostRidistribuzioni)
{
var uor = UorSQL.GetUorFromId(siglaAOO, idUor, dbConfig);
interimSet.Add(uor); //which is the same as: if(!interimSet.Contains(uor))interimSet.Add(uor);
}
visibUtils.Uors = interimSet.ToList();
Vous n'avez même pas besoin de Contient
. Add
sera déjà ne pas ajouter de doublons.
@GSerg, c'est tout à fait vrai, merci. J'ai amélioré ma réponse
UOR uor; foreach (int idUor in visibilitaPostRidistribuzioni) { var uor = UorSQL.GetUorFromId(siglaAOO, idUor, dbConfig); if(!visibUtils.Uors.FirstOrDefault(a => a == uor) { visibUtils.Uors.Add(uor); } }
Utilisez . Dans tous les cas, vous devez parcourir la liste. Si vous voulez une fonction
n log n
, vous devez utiliser unDictionnaire
Vous avez déjà remplacé GetHasCode et Equals, donc c'est très bien. Vous pouvez ensuite utiliser
List.Contains
, mais ce serait exactement" itérer sur la liste visibUtils.Uors et vérifier ". Une manière plus intelligente consiste à utiliser un hashset au lieu d'une liste, oùAdd
renverrait simplement false si l'objet est déjà présent.