3 votes

C# convertir une chaîne formatée (31,2k) en nombre (31240)

Disons que j'ai ce code :

int i = 31240;
string Number = ((double)i / 1000).ToString("0.#k");

J'obtiens ce résultat en tant que chaîne pour Number : 31,2k

Et maintenant, je veux faire exactement l'inverse, c'est-à-dire prendre cette chaîne "31,2k" et la ramener à 31240 ou même à 31200, mais je ne sais pas comment faire... Une idée ?


Quelqu'un a dit que c'était impossible. MAIS j'ai finalement trouvé le moyen parfait d'atteindre mon objectif. Je poste la solution pour ceux qui pourraient être désireux de savoir. L'utilisation est simple, et cela permet de faire 2 types de conversions :

  • Milliers, Exemple : 45831 <=> 45,8k <=> 45831
  • Millions, Exemple : 123852376 <=> 123,5m <=> 123852376

5voto

xanatos Points 30513
int i = (int)(Double.Parse(Number.Substring(0, Number.Length - 1)) * 1000);

Nous supprimons le k avec Number.Substring(0, Number.Length - 1), le transformons en double avec Double.Parse, le multiplions par 1000 et enfin le convertissons en int. L'ordre des opérations est très important! La première fois que j'ai fait (int)Double.Parse(Number.Substring(0, Number.Length - 1)) * 1000, j'ai converti en int avant de multiplier (donc j'ai obtenu 31000 au lieu de 31200)

J'ajouterais que si je devais écrire ce code, je dormirais BEAUCOUP mieux si j'utilisais Decimal.Parse au lieu de Double.Parse (afin d'être à l'abri des caprices des nombres à virgule flottante)

Je vais ajouter une meilleure méthode:

int i2 = int.Parse(Number.Substring(0, Number.Length - 1).Replace(CultureInfo.CurrentCulture.NumberFormat.NumberDecimalSeparator, string.Empty)) * 100;

C'est beaucoup plus intéressant. Nous supprimons le k comme dans l'autre méthode mais cette fois-ci nous supprimons aussi la virgule , de la string et nous multiplions par 100.

Le truc intéressant est qu'au lieu de simplement remplacer la virgule , par une chaîne vide (comme le feraient les bovins en argot italien), nous récupérons le séparateur décimal actuel (CultureInfo.CurrentCulture.NumberFormat.NumberDecimalSeparator) et nous remplaçons CELA par une chaîne vide.

De toute évidence, si nous avions utilisé une autre culture pour composer la chaîne initiale (par exemple la toujours bonne CultureInfo.InvariantCulture), nous utiliserions cela pour obtenir le NumberDecimalSeparator

-1voto

GianT971 Points 1262

Voici la solution que j'ai suivie :

public class StringFromInt
{
    public enum FormatStyle
    {
        Kilo = 1000,
        Mega = 1000000
    }
    public int Number;
    public FormatStyle Format
    {
        get
        {
            switch (LimitValueBeforeConversion)
            {
                case 1000: return FormatStyle.Kilo;
                case 1000000: return FormatStyle.Mega;
                default:
                    throw new NotImplementedException("Vous devez implémenter le code pour ce genre de valeur");
            }
        }
        set
        {
            if (value == FormatStyle.Kilo)
            {
                LimitValueBeforeConversion = 1000;
            }
            else if (value == FormatStyle.Mega)
            {
                LimitValueBeforeConversion = 1000000;
            }
        }
    }
    public int LimitValueBeforeConversion
    { get; set; }
    public static implicit operator int(StringFromInt s)
    {
        return s.Number;
    }
    public static implicit operator StringFromInt(int number)
    {
        StringFromInt s = new StringFromInt(number);
        return s;
    }

    #region Constructors
    public StringFromInt(int number, FormatStyle format)
    {
        this.Number = number;
        Format = format;
    }
    public StringFromInt(int number)
        : this(number, FormatStyle.Kilo)
    {
        if (number >= 1000000)
        {
            this.Format = FormatStyle.Mega;
        }
    }
    #endregion

    public override string ToString()
    {
        if (Number >= LimitValueBeforeConversion)
        {
            string formatString = "0.#k";
            switch (Format)
            {
                case FormatStyle.Kilo:
                    formatString = "0.#k";
                    break;
                case FormatStyle.Mega:
                    formatString = "0.#m";
                    break;
                default:
                    throw new NotImplementedException("Vous devez implémenter le code pour ce genre de valeur");
            }
            return ((double)Number / LimitValueBeforeConversion).ToString(formatString);
        }
        else
        {
            return Number.ToString();
        }
    }
}

Et voici un programme de test :

class Program
{
    static void Main(string[] args)
    {
        int i = 31240;

        string StringRepresentation = ((double)i / 1000).ToString("0.#k");
        int resultBackWithParse = int.Parse(StringRepresentation.Substring(0, StringRepresentation.Length - 1).Replace(CultureInfo.CurrentCulture.NumberFormat.NumberDecimalSeparator, string.Empty)) * 100;
        Console.WriteLine("Nombre de base : " + i.ToString());
        Console.WriteLine(new string('-', 35));
        Console.WriteLine("Représentation en chaîne de caractères : " + StringRepresentation);
        Console.WriteLine("Représentation entière avec Int.Parse : " + resultBackWithParse.ToString());
        Console.WriteLine();
        StringFromInt MySolutionNumber = i;
        int resultBackWithStringFromInt = MySolutionNumber;
        Console.WriteLine("Représentation en chaîne de caractères avec StringFromInt : " + MySolutionNumber.ToString());
        Console.WriteLine("Représentation entière avec StringFromInt : " + resultBackWithStringFromInt);

        Console.WriteLine(new string('=', 35) + "\n");
        i = 123456789;
        StringFromInt MyNumber = 123456789;
        int resultBack = MyNumber;
        Console.WriteLine("Nombre de base : " + i.ToString());
        Console.WriteLine(new string('-', 35));
        Console.WriteLine("Représentation en chaîne de caractères avec StringFromInt : " + MyNumber);
        Console.WriteLine("Représentation entière avec StringFromInt : " + resultBack);

        Console.ReadKey(true);
    }
}

Comme vous pouvez le remarquer, il n'est pas nécessaire d'utiliser l'initialiseur "new", je veux dire qu'il n'est pas nécessaire de faire :

StringFromInt Number = new StringFromInt(YourNumber)

Grâce à l'opérateur implicite, vous pouvez faire :

StringFromInt Number = YourNumber

Je ne sais pas, mais je pense que c'est un bon début, qu'en pensez-vous ?

De toute façon, j'ai réussi à faire ce que je voulais, donc pour les personnes qui pensaient que cela n'était pas possible, vous voyez, c'est possible :-)

Évidemment, cela peut être amélioré : cette version fonctionne uniquement pour les milliers et les millions.

Sincères salutations

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X