J'essaye de multiplier une chaîne a par un entier b tel que a * b = a + a + a ... (b fois) . J'ai essayé de le faire de la même manière que je le ferais en python:

class Test {
    static function main() {
        var a = "Text";
        var b = 4;    
        trace(a * b);    //Assumed Output: TextTextTextText
    }
}

Mais cela soulève:

Échec de la construction Test.hx: 6: caractères 14-15: la chaîne doit être Int

Il ne semble pas y avoir d'informations dans le livre de recettes de programmation Haxe ou la documentation de l'API sur la multiplication des chaînes, donc je me demande si j'ai mal tapé quelque chose ou si je devrais utiliser:

class Test {
    static function main() {
        var a = "Text";
        var b = 4;
        var c = ""; 

        for (i in 0...b) {
            c = c + a;
        }
        trace(c); // Outputs "TextTextTextText"
    }
}
3
0x.dummyVar 1 janv. 2018 à 00:28

5 réponses

Meilleure réponse

Pas très court, mais compréhension de tableau peut aider dans certaines situations:

class Test {
    static function main() {
        var a = "Text";
        var b = 4;
        trace( [for (i in 0...b) a].join("") );
        //Output: TextTextTextText
    }
}

Voir sur try.haxe.org.

3
tokiop 1 janv. 2018 à 15:47

La méthode la plus rapide (au moins sur la cible JavaScript de https://try.haxe.org/#195A8) semble utiliser StringTools._pad.

public static inline function stringProduct ( s : String, n : Int ) {

    if ( n < 0 ) {

        throw ( 1 );

    }

    return StringTools.lpad ( "", s, s.length * n );

}

StringTools.lpad et StringTools.rpad ne semblent pas pouvoir décider lequel est le plus efficace. Il semble que rpad pourrait être meilleur pour les chaînes plus grandes et lpad pourrait être meilleur pour les chaînes plus petites, mais ils changent un peu à chaque réexécution. haxe.format.JsonPrinter utilise lpad pour la concaténation, mais je ne sais pas lequel recommander.

0
0x.dummyVar 5 déc. 2018 à 01:25

L'opérateur de multiplication numérique * nécessite des types numériques, comme un entier. Vous avez une chaîne. Si vous souhaitez multiplier une chaîne, vous devez le faire manuellement en ajoutant une chaîne cible dans la boucle.

L'opérateur + n'est pas le plus numérique dans votre exemple, mais un moyen de combiner des chaînes.

Vous pouvez obtenir ce que vous voulez en surcharge:

abstract MyAbstract(String) {
    public inline function new(s:String) {
        this = s;
    }

    @:op(A * B)
    public function repeat(rhs:Int):MyAbstract {
        var s:StringBuf = new StringBuf();
        for (i in 0...rhs)
            s.add(this);
        return new MyAbstract(s.toString());
    }
}

class Main {
    static public function main() {
        var a = new MyAbstract("foo");
        trace(a * 3); // foofoofoo
    }
}
4
Gama11 18 févr. 2019 à 12:20

Pour construire sur la réponse de tokiop, vous pouvez également définir une fonction times, puis l'utiliser comme extension statique .

using Test.Extensions;

class Test {
    static function main() {
        trace ("Text".times(4));
    }
}

class Extensions {
    public static function times (str:String, n:Int) {
        return [for (i in 0...n) str].join("");
    }
}

Démo try.haxe.org ici

3
bsinky 5 janv. 2018 à 15:53

Pour construire sur la réponse bsinky, vous pouvez également définir une fonction times comme extension statique, mais évitez le tableau:

using Test.Extensions;

class Test {
    static function main() {
        trace ("Text".times(4));
    }
}

class Extensions {
    public static function times (str:String, n:Int) {
        var v = new StringBuf();
        for (i in 0...n) v.add(str);
        return v.toString();
    }
}

Démo: https://try.haxe.org/#e5937

StringBuf peut être optimisé pour différentes cibles. Par exemple, sur la cible JavaScript, il est compilé comme si vous utilisiez simplement des chaînes https: //api.haxe. org / StringBuf.html

2
Mark Knol 9 janv. 2018 à 09:24