Quel est l'équivalent de l'opérateur de jointure sur un vecteur de chaînes?

120

Je n'ai pas pu trouver l'équivalent de Rust pour l'opérateur "join" sur un vecteur de Strings. J'ai un Vec<String>et j'aimerais les rejoindre en tant que célibataire String:

let string_list = vec!["Foo".to_string(),"Bar".to_string()];
let joined = something::join(string_list,"-");
assert_eq!("Foo-Bar", joined);

En relation:

Davide Aversa
la source

Réponses:

153

Dans Rust 1.3.0 et joinversions ultérieures, est disponible:

fn main() {
    let string_list = vec!["Foo".to_string(),"Bar".to_string()];
    let joined = string_list.join("-");
    assert_eq!("Foo-Bar", joined);
}

Avant la 1.3.0, cette méthode s'appelait connect:

let joined = string_list.connect("-");

Notez que vous n'avez rien à importer puisque les méthodes sont automatiquement importées par le prélude de la bibliothèque standard .

MatthewG
la source
7
Cela a peut-être changé, mais SliceConcatExtc'est uniquement la nuit.
5
@Evert Le trait est marqué comme instable, mais ses méthodes sont stables, vous pouvez donc les utiliser. Vous n'avez pas besoin d'expliciter usele trait car il est en prélude.
entre le
1
@shepmaster Si j'ai lu correctement votre 'réponse', il y a un joinin itertools.
Steve Powell le
2
Merci @shepmaster. Malheureusement, votre référence sans fioritures à une autre réponse était plutôt cryptique, de sorte qu'il n'était pas du tout clair quelle partie de cette réponse était pertinente. Bien que vos commentaires, corrections et réponses soient toujours excellents, votre style est condescendant et rebutant.
Steve Powell
10

Il existe une fonction de la itertoolscaisse également appelée joinqui rejoint un itérateur:

extern crate itertools; // 0.7.8

use itertools::free::join;
use std::fmt;

pub struct MyScores {
    scores: Vec<i16>,
}

impl fmt::Display for MyScores {
    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
        fmt.write_str("MyScores(")?;
        fmt.write_str(&join(&self.scores[..], &","))?;
        fmt.write_str(")")?;
        Ok(())
    }
}

fn main() {
    let my_scores = MyScores {
        scores: vec![12, 23, 34, 45],
    };
    println!("{}", my_scores); // outputs MyScores(12,23,34,45)
}
Nick Linker
la source
6
Les utilisateurs de ce code doivent être conscients qu'il alloue une chaîne potentiellement volumineuse juste pour la jeter. Il est plus efficace d'écrire les chaînes directement dans la sortie. Voir aussi Quelle est une manière idiomatique d'imprimer un itérateur séparé par des espaces dans Rust? , Dans Rust, quelle est la meilleure façon d'imprimer quelque chose entre chaque valeur d'un conteneur? .
Shepmaster
2
Compréhensible, bien que la question portait sur la join, pas sur les moyens d'optimiser l'algorithme de formatage, non?
Nick Linker
6
collect+ joinest plus rapide et n'ajoute aucune dépendance, voir l' essentiel pour un benchmark
murlakatamenka