2017-09-02 1 views
2

Je me soucie beaucoup de la capitalisation (probablement trop). J'ai donc écrit une fonction qui fixe la capitalisation partout sur mon site. Je veux essentiellement un "cas de titre" mais à quelques exceptions près ... des mots que je n'aime pas voir capitalisés et des acronymes.PHP - Est-ce un moyen efficace de faire ces changements?

function my_capitals($string) 
{ 
    $uc = ucwords($string); 
    $tokens = explode(' ',$uc); 
    foreach ($tokens as $key=>$val) 
    { 
     if ($val == 'Ipa') $tokens[$key] = 'IPA'; 
     else if ($val == 'Ipas') $tokens[$key] = 'IPAs'; 
     else if ($val == 'Apa') $tokens[$key] = 'APA'; 
     else if ($val == 'Apas') $tokens[$key] = 'APAs'; 
     else if ($val == 'A') $tokens[$key] = 'a'; 
     else if ($val == 'And') $tokens[$key] = 'and'; 
     else if ($val == 'The') $tokens[$key] = 'the'; 
     else if ($val == 'In') $tokens[$key] = 'in'; 
     else if ($val == 'Or') $tokens[$key] = 'or'; 
     else if ($val == 'Of') $tokens[$key] = 'of'; 
     else if ($val == 'To') $tokens[$key] = 'to'; 
     else if ($val == 'On') $tokens[$key] = 'on'; 
     else if ($val == 'At') $tokens[$key] = 'at'; 
     else $tokens[$key] = $val; 
    } 
    $final = implode(' ',$tokens); 
    return $final; 
} 

Imaginez qu'il pourrait y avoir des options 10-15 et qu'il peut être exécuté 3-5 fois par page sur les chaînes relativement courtes (descriptions d'une ligne et titres).

Ma question est la suivante: Est-ce une manière efficace d'accomplir ce genre de traduction? Ou devrais-je trouver un moyen plus efficace de le faire? Y a-t-il une autre alternative que je ne connais pas, par opposition à juste passer qui a probablement des performances similaires?

+0

double possible de [Ce qui est plus rapide et mieux, cas de commutation ou si d'autre si?] (Https://stackoverflow.com/questions/10773047/which-is-faster-and-better-switch-case -ou-si-autre-si) – Haroon

+0

Que diriez-vous de nouvelles capitales de ligne? Vous voulez aussi les minuscules? – deg

+0

@deg, je n'avais pas envisagé de nouvelles lignes capitales ... Je ne sais pas si celles-ci ne sont pas prises par ma situation actuelle. – JessycaFrederick

Répondre

0

je le ferais de cette façon:

function my_capitals($string) 
    { 
     $uc = ucwords($string); 
     $tokens = explode(' ',$uc); 
     $excepsions = ['Ipa'=>'IPA','Ipas'=>'IPAs']; 
     foreach ($tokens as $key=>$val) 
     { 
      if(isset($excepsions[$val])){ 
       $tokens[$key] = $excepsions[$val]; 
      } 
     } 
     $final = implode(' ',$tokens); 
     return $final; 
    } 
+0

J'ai commencé à faire C'est comme un «refactor», mais je ne savais pas si cela finirait par être plus efficace. Merci pour votre suggestion – JessycaFrederick

+1

Il vous manque un crochet de fermeture dans votre clause 'isset' – rndus2r

+0

@ rndus2r merci. Quoi qu'il en soit, je pense que votre réponse est beaucoup mieux –

2

Tout d'abord, vous devez considérer ce efficace signifie pour vous. Vous cherchez

  • le temps d'exécution le plus
  • l'impact du plus petit système (CPU, RAM, E/S ...)
  • le code plus propre (codage efficace)
  • le plus court Code
  • ...

Deuxièmement, étant donné que vos coordonnées ...

  1. il y a environ 30 termes de recherche
  2. cordes sont courtes
  3. et le code est tiré jusqu'à 5 fois

... sauf si vous utilisez un grille-pain pour votre script, ni le temps d'exécution, ni système l'impact vous donnera n'importe quel type de mal de tête.

Donc c'est vraiment un code propre. Par conséquent, vous devez connaître la différence entre == et ===. Ensuite, vous avez déjà une chaîne qui est consultable pour plusieurs fonctions spécifiques aux chaînes : $uc.

Alors qu'en est-il de str_replace? Il accepte les tableaux en entrée.

function my_capitals($string) 
{ 
    $uc = " ".ucwords($string)." "; 
    $search = [' Ipa ', ' Ipas ', ' A ', ' Bändy ']; 
    $replacements = [' IPA ', ' IPAs ', ' a ', ' Cändy ']; 
    return ucfirst(trim(str_replace($search, $replacements, $uc))); 
} 

Vous pouvez même raccourcir ce à 1 ligne:

function my_capitals($string) 
{ 
    return ucfirst(trim(str_replace([' Ipa ', ' Ipas ', ' A ', ' Bändy '], [' IPA ', ' IPAs ', ' a ', ' Cändy '], " ".ucwords($string)." "))); 
} 

Assurez-vous $search et $replacements ne contiennent une quantité égale d'éléments et les deux ont avant et arrière des espaces blancs.

L'attribution de vos baies une seule fois améliorera la vitesse des appels consécutifs.

function my_capitals1a($string, $searcher, $replacement) 
{ 
    return ucfirst(trim(str_replace($searcher,$replacement, " ".ucwords($string)." "))); 
} 

comparaison de démonstration et la vitesse: http://sandbox.onlinephpfunctions.com/code/fd594ab47b78778981dc0a58432e141f48f9b6e7

Edit: mot de remplacement en toute sécurité Edit2: comparaison de la vitesse Edit3: améliorée avec des notes de @Pogrock

+1

Vous pouvez avoir besoin d'espaces de fin sur ceux-ci. par exemple. 'Andy'. – Progrock

+0

Merci de fournir un cadre pour réfléchir aux choses. Je suis particulièrement intéressé par le temps d'exécution le plus court. Je suis le seul à lire le code et même si je fais des commentaires généreux pour ma propre santé mentale, les codes clean/short ne sont pas les priorités absolues pour moi. J'ai déjà passé en revue == vs ===. Je suis d'abord venu à comprendre que la différence est de type et puisque ce seront tous des cordes, alors j'ai pensé que j'étais bien avec ==. Il s'avère que === est plus rapide, alors merci !!). J'explorerai l'efficacité de str_replace. Merci! – JessycaFrederick

+0

@Progrock merci de souligner cela, j'ai mis à jour la réponse – rndus2r

0

Une légère variation du code de l'OP. Majuscules tous les mots dans le titre d'entrée, puis échanger des mots comme et pour et. Enfin, initialisez le début du titre.

Vous pouvez canonicaliser votre titre d'abord avec une chaîne à la baisse, mais cela pourrait casser des noms tels que O'Hagan.

Il existe de nombreux autres cas de contours non couverts, et il est préférable de négocier la vitesse pour une bibliothèque complète.

<?php 
$replacements = [ 
     'Ipas' => 'IPAs', 
     'Apa' => 'APA', 
     'Apas' => 'APAs', 
     'A' => 'a', 
     'And' => 'and', 
     'The' => 'the', 
     'In' => 'in', 
     'Or' => 'or', 
     'Of' => 'of', 
     'To' => 'to', 
     'On' => 'on', 
     'At' => 'at', 
]; 

$test_titles = [ 
    'a tale of two cities' => 'A Tale of Two Cities', 
    'the secret history'  => 'The Secret History', 
    'lord of the flies'  => 'Lord of the Flies', 
    'The woman in white'  => 'The Woman in White', 
    'of mice and men'   => 'Of Mice and Men', 
    'the andy warhol diaries' => 'The Andy Warhol Diaries' 
]; 

foreach($test_titles as $input => $title_cased) { 
    $words = []; 
    foreach(explode(' ', ucwords($input)) as $word) { 
     $words[] = isset($replacements[$word]) ? $replacements[$word] : $word; 
    } 
    $transformed = ucfirst(implode(' ', $words)); 
    assert($transformed === $title_cased); 
} 
+0

Wheres la différence à @Andriy Lozynskiy réponse? – rndus2r

+0

@ rndus2r où dois-je commencer? Leur fonction a une erreur de syntaxe, et ne fonctionne pas même si corrigé – Progrock

+0

Il manque juste a) et cela fonctionne correctement: http://sandbox.onlinephpfunctions.com/code/b84dd027760e073c147da0a4f0831ed851d2fd71 – rndus2r