Split les colonnes d'un fichier.csv dans des listes de string
Résolu/Fermé
astrocurieux
Messages postés
334
Date d'inscription
mardi 24 février 2015
Statut
Membre
Dernière intervention
29 novembre 2019
-
Modifié le 4 janv. 2019 à 10:19
Whismeril Messages postés 18279 Date d'inscription mardi 11 mars 2003 Statut Contributeur Dernière intervention 17 mars 2023 - 17 janv. 2019 à 19:27
Whismeril Messages postés 18279 Date d'inscription mardi 11 mars 2003 Statut Contributeur Dernière intervention 17 mars 2023 - 17 janv. 2019 à 19:27
A voir également:
- Split les colonnes d'un fichier.csv dans des listes de string
- Split cam - Télécharger - Messagerie
- Le fichier contient une liste de prénoms. triez ce tableau par ordre alphabétique des prénoms. quel mot est formé par les 6 premières lettres de la colonne code ? - Forum Bureautique
- Triez la liste comme sur cette illustration (attention, on ne voit que le début …). quel est le mot formé par les 6 dernières lettres de la colonne code ? - Forum Excel
- Liste de numéro de téléphone suspect 07 ✓ - Forum Mobile
- Cannot access offset of type string on string - Forum PHP
1 réponse
Whismeril
Messages postés
18279
Date d'inscription
mardi 11 mars 2003
Statut
Contributeur
Dernière intervention
17 mars 2023
888
Modifié le 4 janv. 2019 à 14:12
Modifié le 4 janv. 2019 à 14:12
Bonjour
sans un exemple de fichier source qui ne marche pas très difficile de te répondre.
En plus utiliser des listes n'est pas cohérent du Join, un join ça construit une string à partir d'une collection.
Donc tes 2 résultats sont deux string.
Par contre sur le fond, l'erreur de base est de faire 2 listes.
C# est un langage tout objet, ce qui dans la pratique veut dire qu'il est optimisé pour que l'on écrive et utilise ses propres objets.
Si j'avais à charger en mémoire 2 informations d'un csv, je construirais une liste (une vraie) d'objets correspondant à mon besoin.
Pour l'exemple, on va dire que la colonne 1 est remplie (ou pas) d'entiers positifs et la 2 de texte.
Mon objet peut se résumer à
Je veux pouvoir initier cet en objet en faisant un new avec la ligne du csv en paramètre, je dois donc ajouter un constructeur. Dans ce constructeur, je vais gérer les cas où des "cases" du csv seraient manquantes ou vides.
Je décompose bien pour qu'il n'y ait pas d'ambiguïté.
Enfin, pour afficher le contenue, je vais écrire ma propre méthode ToString, qui remplacera celle par défaut.
Le csv est
Pour charger et afficher les données
Résultat
De cette façon, quand il manque une valeur, l'instance existe quand même.
Ce qui n'est pas le cas avec ton codes et à chaque valeur manquante ou incorrecte tu as un décalage.
Quand j'étais petit, la mer Morte n'était que malade.
George Burns
sans un exemple de fichier source qui ne marche pas très difficile de te répondre.
En plus utiliser des listes n'est pas cohérent du Join, un join ça construit une string à partir d'une collection.
Donc tes 2 résultats sont deux string.
Par contre sur le fond, l'erreur de base est de faire 2 listes.
C# est un langage tout objet, ce qui dans la pratique veut dire qu'il est optimisé pour que l'on écrive et utilise ses propres objets.
Si j'avais à charger en mémoire 2 informations d'un csv, je construirais une liste (une vraie) d'objets correspondant à mon besoin.
Pour l'exemple, on va dire que la colonne 1 est remplie (ou pas) d'entiers positifs et la 2 de texte.
Mon objet peut se résumer à
public DonneesAstrocurieux
{
public int Entier {get; set;} //une propriété en lecture et écriture publiques qui contiendra l'entier d'une ligne
public string Texte {get; set;} //une propriété qui en contiendra le texte
}
Je veux pouvoir initier cet en objet en faisant un new avec la ligne du csv en paramètre, je dois donc ajouter un constructeur. Dans ce constructeur, je vais gérer les cas où des "cases" du csv seraient manquantes ou vides.
Je décompose bien pour qu'il n'y ait pas d'ambiguïté.
public class DonneesAstrocurieux
{
/// <summary>
/// Constructeur, prenant en paramètre une ligne de csv
/// </summary>
/// <param name="LigneCsv">La ligne de csv qui sert à construire cette instanc</param>
public DonneesAstrocurieux(string LigneCsv)
{
string[] donnees = LigneCsv.Split(';');
Entier = -99;// -99 est la valeur indiquant une erreur
Texte = string.Empty; //"" est la valeur indiquant une erreur
if (donnees.Length > 0)//s'il y a au moins une donnée dans le tableau
{
int entier;
if (int.TryParse(donnees[0], out entier))
Entier = entier; //si la "case" contient un entier, on l'affecte à la propriété
}
if (donnees.Length > 1)//s'il y a au moins 2 données dans la tableau
Texte = donnees[1];
}
public int Entier { get; set; } //une propriété en lecture et écriture publiques qui contiendra l'entier d'une ligne
public string Texte { get; set; } //une propriété qui en contiendra le texte
}
Enfin, pour afficher le contenue, je vais écrire ma propre méthode ToString, qui remplacera celle par défaut.
public class DonneesAstrocurieux
{
/// <summary>
/// Constructeur, prenant en paramètre une ligne de csv
/// </summary>
/// <param name="LigneCsv">La ligne de csv qui sert à construire cette instanc</param>
public DonneesAstrocurieux(string LigneCsv)
{
string[] donnees = LigneCsv.Split(';');
Entier = -99;// -99 est la valeur indiquant une erreur
Texte = string.Empty; //"" est la valeur indiquant une erreur
if (donnees.Length > 0)//s'il y a au moins une donnée dans le tableau
{
int entier;
if (int.TryParse(donnees[0], out entier))
Entier = entier; //si la "case" contient un entier, on l'affecte à la propriété
}
if (donnees.Length > 1)//s'il y a au moins 2 données dans la tableau
Texte = donnees[1];
}
public int Entier { get; set; } //une propriété en lecture et écriture publiques qui contiendra l'entier d'une ligne
public string Texte { get; set; } //une propriété qui en contiendra le texte
/// <summary>
/// ToString écrasant la méthode par défaut
/// </summary>
/// <returns></returns>
/// <remarks>la méthode par défaut retourne le nom de la classe</remarks>
public override string ToString()
{
return string.Format("L'entier est '{0}', le texte est '{1}'", Entier, Texte);
}
}
Le csv est
Entier;Texte
1;Texte 1
2;Texte 2;
;Texte 3
4
5;Texte 5
6;Texte 6
;
8;Texte 8
9;
10;Texte 10
;Texte 11
13;Texte 13
Pour charger et afficher les données
List<DonneesAstrocurieux> donnees = File.ReadAllLines("astrocurieux.csv").Skip(1).Select(l => new DonneesAstrocurieux(l)).ToList();
foreach (DonneesAstrocurieux item in donnees)
Console.WriteLine(item.ToString());
Résultat
L'entier est '1', le texte est 'Texte 1'
L'entier est '2', le texte est 'Texte 2'
L'entier est '-99', le texte est 'Texte 3'
L'entier est '4', le texte est ''
L'entier est '5', le texte est 'Texte 5'
L'entier est '6', le texte est 'Texte 6'
L'entier est '-99', le texte est ''
L'entier est '8', le texte est 'Texte 8'
L'entier est '9', le texte est ''
L'entier est '10', le texte est 'Texte 10'
L'entier est '-99', le texte est 'Texte 11'
L'entier est '-99', le texte est ''
L'entier est '13', le texte est 'Texte 13'
De cette façon, quand il manque une valeur, l'instance existe quand même.
Ce qui n'est pas le cas avec ton codes et à chaque valeur manquante ou incorrecte tu as un décalage.
Quand j'étais petit, la mer Morte n'était que malade.
George Burns
17 janv. 2019 à 14:38
je pensais t'avoir répondue depuis longtemps mais je m’aperçois que non ...
sincèrement désolé.
17 janv. 2019 à 19:27