2010-05-04 12 views
0

J'ai un modèle Ruby-on-Rails:Quel est le moyen le plus rapide de valider qu'un champ n'a pas plus de n mots?

class Candidate < ActiveRecord::Base 
    validates_presence_of :application_essay 
    validate :validate_length_of_application_essay 

    protected 

    def validate_length_of_application_essay 
    return if application_essay.blank? # don't add a second error message if they didn't fill it out 
    errors.add(:application_essay, :too_long), unless ... 
    end 
end 

Sans tomber dans C, ce qui est le meilleur moyen de vérifier que le application_essay ne contient pas plus de 500 mots? Vous pouvez supposer que la plupart des essais seront d'au moins 200 mots, ne seront probablement pas plus de 5000 mots, et sont en anglais (ou pseudo-anglais parfois appelé "business-ese"). Vous pouvez également classer tout ce que vous voulez comme un "mot" tant que votre classification serait immédiatement évidente pour un utilisateur typique. (NB: ce n'est pas l'endroit pour débattre de ce qu'est un "utilisateur typique" :))

Répondre

1

Je voudrais simplement utiliser quelque chose comme:

string.split(" ").length <= 500 

Quel problème de performance Constatez-vous? Une chaîne de 500 mots environ ne devrait pas poser de problème.

+0

Cela comptera tout ce qui est enveloppé avec des espaces, y compris ''-''. –

2

Vous n'obtiendrez pas plus rapidement qu'une recherche linéaire, désolé (sauf si c'est pour un éditeur de texte quelconque , et vous pouvez suivre de façon incrémentielle)

+0

Mais une recherche linéaire pour quoi? Les espaces? Word-limites? Quel est le minimum d'informations dont je dois tenir compte pendant que je fais la recherche linéaire? Et si je cherche juste des groupes d'espaces, une stratégie de division et de conquête ne m'amènerait-elle pas de O (n) à O (log (n))? –

+1

@James: Si vous cherchiez seulement UN espace, et que la chaîne a été triée par caractère ASCII, alors oui, cela pourrait être vrai. Cependant, pour compter le nombre TOTAL de mots, vous devrez lire chaque caractère dans la chaîne entière (une manière, de haut en bas de ma tête, serait de couper la chaîne, compter les caractères où 'str [i] = = '' && str [i-1]! = '' ', et ajoutez 1) –

1

Vous pouvez estimer la taille typique d'un mot et deviner la quantité de mots en divisant.

quelques conseils ici: http://blogamundo.net/lab/wordlengths/

Vous pouvez essayer comme 5.1 et voir comment vous êtes précis en exécutant quelques tests.

Eh bien probablement diviser par 6,1 puisque vous avez des espaces. Gardez à l'esprit que vous supposez que votre texte n'est pas seulement une énorme quantité d'espaces blancs ou quelque chose comme ça. Eh bien, mais si vous êtes vraiment juste intéressé de vous assurer qu'il n'a pas plus de x mots. Vous pouvez essayer un nombre faible sur x peut-être 5 et s'il a moins de x fois 5 caractères, vous pouvez être sûr qu'il n'a pas plus de x mots.

Donc, vous feriez peut-être mieux de faire une recherche linéaire comme indiqué dans les autres réponses. Une recherche linéaire n'est pas si mauvaise du tout. Cela dépend simplement de ce que vous voulez faire.

+0

J'ai pensé à ça. Je n'ai aucune idée de ce qu'il faut utiliser comme un "mot tyipcal", mais je ne suis pas vraiment opposé au concept si je pouvais trouver une valeur raisonnable. –

+0

J'ai mis à jour mon message. – HansDampf

+0

Et concernant votre commentaire dans l'autre réponse: Je ne pense pas que vous pouvez l'obtenir plus vite que linéaire, pour trouver les mots il n'y a pas moyen de vérifier chaque caractère, ce qui signifie que vous avez au moins n opérations de longueur n minimum . – HansDampf

7

Dans Rails3, l'utilisation d'un :tokenizer avec une méthode lambda fonctionne également.

validates_length_of :essay, :minimum => 100, :too_short => "Your essay must be at least 100 words."), :tokenizer => lambda {|str| str.scan(/\w+/) } 

Ce n'est peut-être pas le plus rapide, mais c'est certainement le moyen le plus propre.

+1

Et c'est plus précis. La réponse sélectionnée comptera tout ce qui est délimité par des espaces blancs, y compris la ponctuation. Votre solution ignore au moins la ponctuation. :-) –

+0

Y at-il un moyen de mettre cela dans une méthode? –