Comment puis-je supprimer les doublons d'un tableau C#?
j'ai travaillé avec un tableau string[]
dans C# qui est retourné d'un appel de fonction. Je pourrais peut-être jouer dans une collection Generic
, mais je me demandais s'il y avait une meilleure façon de le faire, peut-être en utilisant un tableau temporaire.
Quelle est la meilleure façon de supprimer les doublons d'un tableau C#?
20 réponses
vous pouvez éventuellement utiliser une requête LINQ pour faire ceci:
int[] s = { 1, 2, 3, 3, 4};
int[] q = s.Distinct().ToArray();
, Voici le HashSet
public static string[] RemoveDuplicates(string[] s)
{
HashSet<string> set = new HashSet<string>(s);
string[] result = new string[set.Count];
set.CopyTo(result);
return result;
}
malheureusement cette solution nécessite aussi .net framework 3.5 ou plus tard car le HashSet n'a pas été ajouté avant cette version. Vous pouvez également utiliser le tableau .Distinct () , qui est une caractéristique de LINQ.
si vous avez besoin de le trier, alors vous pouvez mettre en œuvre un sort qui élimine également les doublons.
tue deux oiseaux d'une pierre, alors.
cela pourrait dépendre de combien vous voulez concevoir la solution - si le tableau ne sera jamais aussi grand et vous ne vous souciez pas de trier la liste, vous pourriez vouloir essayer quelque chose similaire à ce qui suit:
public string[] RemoveDuplicates(string[] myList) {
System.Collections.ArrayList newList = new System.Collections.ArrayList();
foreach (string str in myList)
if (!newList.Contains(str))
newList.Add(str);
return (string[])newList.ToArray(typeof(string));
}
le code testé et fonctionnel suivant supprimera les doublons d'un tableau. Vous devez inclure le Système.Espace de noms des Collections.
string[] sArray = {"a", "b", "b", "c", "c", "d", "e", "f", "f"};
var sList = new ArrayList();
for (int i = 0; i < sArray.Length; i++) {
if (sList.Contains(sArray[i]) == false) {
sList.Add(sArray[i]);
}
}
var sNew = sList.ToArray();
for (int i = 0; i < sNew.Length; i++) {
Console.Write(sNew[i]);
}
vous pourriez envelopper ceci dans une fonction si vous le vouliez.
-- C'est question D'Interview demandé à chaque fois. Maintenant j'ai fait son codage.
static void Main(string[] args)
{
int[] array = new int[] { 4, 8, 4, 1, 1, 4, 8 };
int numDups = 0, prevIndex = 0;
for (int i = 0; i < array.Length; i++)
{
bool foundDup = false;
for (int j = 0; j < i; j++)
{
if (array[i] == array[j])
{
foundDup = true;
numDups++; // Increment means Count for Duplicate found in array.
break;
}
}
if (foundDup == false)
{
array[prevIndex] = array[i];
prevIndex++;
}
}
// Just Duplicate records replce by zero.
for (int k = 1; k <= numDups; k++)
{
array[array.Length - k] = '"151900920"';
}
Console.WriteLine("Console program for Remove duplicates from array.");
Console.Read();
}
protected void Page_Load(object sender, EventArgs e)
{
string a = "a;b;c;d;e;v";
string[] b = a.Split(';');
string[] c = b.Distinct().ToArray();
if (b.Length != c.Length)
{
for (int i = 0; i < b.Length; i++)
{
try
{
if (b[i].ToString() != c[i].ToString())
{
Response.Write("Found duplicate " + b[i].ToString());
return;
}
}
catch (Exception ex)
{
Response.Write("Found duplicate " + b[i].ToString());
return;
}
}
}
else
{
Response.Write("No duplicate ");
}
}
List<String> myStringList = new List<string>(); foreach (string s in myStringArray) { if (!myStringList.Contains(s)) { myStringList.Add(s); } }
C'est O(N^2) , qui n'aura pas d'importance pour une courte liste qui va être fourrée dans un combo, mais pourrait être rapidement un problème sur une grande collection.
ajouter toutes les chaînes à un dictionnaire et obtenir la propriété Keys après. Cela produira chaque chaîne de caractères unique, mais pas nécessairement dans le même ordre que votre entrée originale.
si vous avez besoin que le résultat final ait le même ordre que l'entrée originale, lorsque vous considérez la première occurrence de chaque chaîne, utilisez l'algorithme suivant à la place:
- ont une liste (sortie finale) et un dictionnaire (à vérifier pour duplicata)
- pour chaque chaîne dans l'entrée, vérifier si elle existe déjà dans le dictionnaire
- si ce n'est pas le cas, ajoutez-le au dictionnaire et à la liste
à la fin, la liste contient la première occurrence de chaque chaîne unique.
assurez-vous que vous considérez des choses comme la culture et tel lors de la construction de votre dictionnaire, pour s'assurer que vous manipulez des doubles avec des lettres accentuées correctement.
le morceau de code suivant tente de supprimer les doublons d'un ArrayList bien que ce ne soit pas une solution optimale. On m'a posé cette question au cours d'une entrevue pour enlever les doublons par récursion, et sans utiliser un arraylist second/temp:
private void RemoveDuplicate()
{
ArrayList dataArray = new ArrayList(5);
dataArray.Add("1");
dataArray.Add("1");
dataArray.Add("6");
dataArray.Add("6");
dataArray.Add("6");
dataArray.Add("3");
dataArray.Add("6");
dataArray.Add("4");
dataArray.Add("5");
dataArray.Add("4");
dataArray.Add("1");
dataArray.Sort();
GetDistinctArrayList(dataArray, 0);
}
private void GetDistinctArrayList(ArrayList arr, int idx)
{
int count = 0;
if (idx >= arr.Count) return;
string val = arr[idx].ToString();
foreach (String s in arr)
{
if (s.Equals(arr[idx]))
{
count++;
}
}
if (count > 1)
{
arr.Remove(val);
GetDistinctArrayList(arr, idx);
}
else
{
idx += 1;
GetDistinctArrayList(arr, idx);
}
}
peut-être un hashset qui ne stocke pas les éléments dupliqués et ignore silencieusement les requêtes pour ajouter dupliquer.
static void Main()
{
string textWithDuplicates = "aaabbcccggg";
Console.WriteLine(textWithDuplicates.Count());
var letters = new HashSet<char>(textWithDuplicates);
Console.WriteLine(letters.Count());
foreach (char c in letters) Console.Write(c);
Console.WriteLine("");
int[] array = new int[] { 12, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2 };
Console.WriteLine(array.Count());
var distinctArray = new HashSet<int>(array);
Console.WriteLine(distinctArray.Count());
foreach (int i in distinctArray) Console.Write(i + ",");
}
Voici une o(n*n) approche qui utilise O(1) espace.
void removeDuplicates(char* strIn)
{
int numDups = 0, prevIndex = 0;
if(NULL != strIn && *strIn != '"151900920"')
{
int len = strlen(strIn);
for(int i = 0; i < len; i++)
{
bool foundDup = false;
for(int j = 0; j < i; j++)
{
if(strIn[j] == strIn[i])
{
foundDup = true;
numDups++;
break;
}
}
if(foundDup == false)
{
strIn[prevIndex] = strIn[i];
prevIndex++;
}
}
strIn[len-numDups] = '"151900920"';
}
}
les approches hash/linq ci-dessus sont ce que vous utiliseriez généralement dans la vie réelle. Toutefois, dans les interviews, ils veulent généralement mettre certaines contraintes, par exemple un espace constant qui exclut le hachage ou pas de api - qui exclut l'utilisation de LINQ .
NOTE: non testé!
string[] test(string[] myStringArray)
{
List<String> myStringList = new List<string>();
foreach (string s in myStringArray)
{
if (!myStringList.Contains(s))
{
myStringList.Add(s);
}
}
return myStringList.ToString();
}
pourrait faire ce dont vous avez besoin...
MODIFIER Argh!!! battu par rob en moins d'une minute!
testé ci-dessous & cela fonctionne. Ce qui est cool, c'est qu'il fait une recherche sensible à la culture trop
class RemoveDuplicatesInString
{
public static String RemoveDups(String origString)
{
String outString = null;
int readIndex = 0;
CompareInfo ci = CultureInfo.CurrentCulture.CompareInfo;
if(String.IsNullOrEmpty(origString))
{
return outString;
}
foreach (var ch in origString)
{
if (readIndex == 0)
{
outString = String.Concat(ch);
readIndex++;
continue;
}
if (ci.IndexOf(origString, ch.ToString().ToLower(), 0, readIndex) == -1)
{
//Unique char as this char wasn't found earlier.
outString = String.Concat(outString, ch);
}
readIndex++;
}
return outString;
}
static void Main(string[] args)
{
String inputString = "aAbcefc";
String outputString;
outputString = RemoveDups(inputString);
Console.WriteLine(outputString);
}
}
-- AptSenSDET
ce code supprime 100% les valeurs dupliquées d'un tableau[comme j'ai utilisé un[i]].....Vous pouvez le convertir dans n'importe quelle langue OO..... :)
for(int i=0;i<size;i++)
{
for(int j=i+1;j<size;j++)
{
if(a[i] == a[j])
{
for(int k=j;k<size;k++)
{
a[k]=a[k+1];
}
j--;
size--;
}
}
}
solution Simple:
using System.Linq;
...
public static int[] Distinct(int[] handles)
{
return handles.ToList().Distinct().ToArray();
}
vous pouvez utiliser ce code quand vous travaillez avec un ArrayList
ArrayList arrayList;
//Add some Members :)
arrayList.Add("ali");
arrayList.Add("hadi");
arrayList.Add("ali");
//Remove duplicates from array
for (int i = 0; i < arrayList.Count; i++)
{
for (int j = i + 1; j < arrayList.Count ; j++)
if (arrayList[i].ToString() == arrayList[j].ToString())
arrayList.Remove(arrayList[j]);
public static int RemoveDuplicates(ref int[] array)
{
int size = array.Length;
// if 0 or 1, return 0 or 1:
if (size < 2) {
return size;
}
int current = 0;
for (int candidate = 1; candidate < size; ++candidate) {
if (array[current] != array[candidate]) {
array[++current] = array[candidate];
}
}
// index to count conversion:
return ++current;
}
ci-dessous est une logique simple en java vous parcourez les éléments de tableau deux fois et si vous voyez un même élément vous lui assignez Zéro plus vous ne touchez pas l'index de l'élément que vous comparez.
import java.util.*;
class removeDuplicate{
int [] y ;
public removeDuplicate(int[] array){
y=array;
for(int b=0;b<y.length;b++){
int temp = y[b];
for(int v=0;v<y.length;v++){
if( b!=v && temp==y[v]){
y[v]=0;
}
}
}
}
private static string[] distinct(string[] inputArray)
{
bool alreadyExists;
string[] outputArray = new string[] {};
for (int i = 0; i < inputArray.Length; i++)
{
alreadyExists = false;
for (int j = 0; j < outputArray.Length; j++)
{
if (inputArray[i] == outputArray[j])
alreadyExists = true;
}
if (alreadyExists==false)
{
Array.Resize<string>(ref outputArray, outputArray.Length + 1);
outputArray[outputArray.Length-1] = inputArray[i];
}
}
return outputArray;
}