Efficacement fusionner les tableaux de chaîne dans .NET, en gardant les valeurs distinctes
Je suis en utilisant .NET 3.5. J'ai deux tableaux de chaîne, qui peuvent partager une ou plusieurs valeurs:
string[] list1 = new string[] { "apple", "orange", "banana" };
string[] list2 = new string[] { "banana", "pear", "grape" };
Je voudrais un moyen de les fusionner en un seul tableau avec pas de doublons:
{ "apple", "orange", "banana", "pear", "grape" }
Je peux le faire avec LINQ:
string[] result = list1.Concat(list2).Distinct().ToArray();
mais j'imagine que ce n'est pas très efficace pour les grandes baies.
Est-il un meilleur moyen?
Vous devez vous connecter pour publier un commentaire.
de msdn: "Cette méthode exclut les doublons de retour ensemble. Ce comportement diffère de la méthode Concat(TSource) méthode, qui renvoie tous les éléments de l'entrée séquences, y compris les doublons."
Pourquoi pensez-vous qu'il serait inefficace? Pour autant que je suis conscient, à la fois Concat et Distincts, sont évalués paresseusement, à l'aide d'un HashSet derrière les scènes Distinctes pour garder une trace des éléments qui ont déjà été retournés.
Je ne suis pas sûr comment vous pouvez gérer pour le rendre plus efficaces que d'une manière générale 🙂
EDIT: Distinctes utilise Set (une classe interne) au lieu de HashSet, mais l'essentiel est toujours correcte. C'est vraiment un très bon exemple de la façon soignée LINQ est. La réponse la plus simple est à peu près aussi efficace que vous pouvez atteindre sans plus de connaissances du domaine.
L'effet est l'équivalent de:
.NET 3.5 introduit la classe HashSet qui pourrait faire ceci:
Pas sûr de la performance, mais il devrait battre le Linq exemple que vous avez donné.
EDIT:
Je corrige la position des mains. Le paresseux de la mise en œuvre de Concat et Distinctes avoir une clé de mémoire ET de vitesse. Concat/Distinct est environ 10% plus rapide, et enregistre plusieurs copies de données.
J'ai confirmé à l'aide de code:
est la sortie de:
Avertissement C'est l'optimisation prématurée. Pour votre exemple des tableaux, utiliser le 3.5 méthodes d'extension. Jusqu'à ce que vous savez que vous avez un problème de performance dans cette région, vous devez utiliser le code de bibliothèque.
Si vous pouvez trier les tableaux, ou ils sont triés quand vous arrivez à ce point dans le code, vous pouvez utiliser les méthodes suivantes.
Ces va tirer un seul élément à la fois, et de produire le "plus" de l'élément, puis chercher un nouvel élément à partir de la source correspondante, jusqu'à ce que les deux sources sont épuisés. Dans le cas où l'élément actuel récupérée à partir de ces deux sources sont égaux, il va produire l'une à partir de la première source, et de les ignorer dans les deux sources.
Noter que si l'une des sources contient des doublons, vous pouvez voir les doublons dans la sortie. Si vous souhaitez supprimer ces doublons dans les listes triées, utilisez la méthode suivante:
Noter qu'aucun de ces en interne l'utilisation d'une structure de données à conserver une copie des données, de sorte qu'ils seront bon marché si l'entrée est triée. Si vous ne pouvez pas ou ne voulez pas vous garantir que, vous devez utiliser l'3.5 méthodes d'extension que vous avez déjà trouvé.
Voici un exemple de code qui appelle les méthodes ci-dessus:
Probablement la création d'une table de hachage avec vos valeurs en tant que touches (uniquement l'ajout de ceux qui ne sont pas déjà présent), puis en convertissant les clés d'un tableau pourrait être une solution viable.
Vous ne savez pas où l'approche est plus rapide, jusqu'à ce que vous mesurez. Le LINQ façon est élégant et facile à comprendre.
Une autre façon est de mettre en œuvre un ensemble comme un tableau de hachage (Dictionnaire) et ajoutez tous les éléments des deux tableaux à l'ensemble. Puis utiliser.Les touches.Méthode ToArray() pour créer le tableau résultant.