Newsgroup: it.comp.lang.javascript
Titolo: ricerca su stringa soluzione piu veloce

avendo un array del genere
  1-107
 19-144
 19-145
 19-146
200-60
200-61
 20-87
 20-90
 20-91
120-40
120-41
dovendo trovare tutti i 20 ho ipotizzato varie soluzioni:
a 20 aggiungo - ed ho 20-;
quindi cerca tutti i 20- a partire dal primo elemento della stringa (quindi
evita l'erroe di trovare 120 o 200)
oppure 
cerca 20 a partire dal primo elemento della stringa ma solo se il terzo è
-; in realtà qundi sta cercando 20-
oppure dovrei riscrivere la lista cosi
001-107
019-144
019-145
019-146
200-60
200-61
020-87
020-90
020-91
120-40
120-41
quindi la ricerca la fa direttemente sui primi tre caratteri, quindi
cercherà 020; non so se molto piu' veloce
-----------------
e se array era del tipo 
  1,107
 19,144
 19,145
o
  1.107
 19.144
 19.145
dove la posto del - vi è la , o il . la rcerca è più veloce degli elemti
prima della , o del .?
in qunato a questo punto avrei un arra non più stringa ma un array
numerico;
dovendo però sempre cercare solo la prima parte e non tutto il numero

 : a 20 aggiungo - ed ho 20-;
E' irrilevante se e cosa metti davanti a 20, basta che indichi come 
parametro cosa cercare
Altrimenti per browser recenti esiste il metodo filter(), qua forniscono 
anche un prototype per i browser che non lo supportano:
https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/
Array/filter

 dovendo però sempre cercare solo la prima parte e non tutto il numero
Metti che devi cercare solo quelle che iniziano con 19, la tua
condizione sarebbe: value >= 19 && value < 20
Puoi ovviamente anche troncare il numero e verificare la parte intera:
value |0 === 19
In termini di performance, non so quale sia il più veloce tra i due,
andrebbe fatto un profiling. Considera però, a meno di strafalcioni
assurdi, che è buona regola scrivere prima del buon codice, e
ottimizzare successivamente. Quindi a meno che tu non abbia un array
enorme che ti da problemi di performance su questo genere di ricerca, io
non mi preoccuperei prematuramente.
-- 
"When you have eliminated the impossible, whatever remains, however
improbable, must be the truth."

 anche un prototype per i browser che non lo supportano:
Opterei per questo, piuttosto che aggiungere un nuovo metodo. In questo
modo nei browser che supportano nativamente il metodo, è più veloce, e
si scrive comunque codice ES5 standard. Inoltre ci sono già diversi
scripts pubblici per lo shim laddove i browser non supportano le
specifiche ES5.


Il 15/08/2011 10:45, Cristiano Larghi ha scritto:
Capitato qua per caso, non conosco javascript... Ma non funzionano le 
regexp?   
http://www.regular-expressions.info/javascript.html
la regexp  \D20\D  fa al caso tuo indica un 20 che non deve essere 
preceduto o seguito da una cifra
#!/usr/bin/perl -w
$a[0]=">     1-107";
$a[1]=">    19-144";
$a[2]=">    19-145";
$a[3]=">    19-146";
$a[4]=">  200-60";
$a[5]=">  200-61";
$a[6]=">    20-87";
$a[7]=">    20-90";
$a[8]=">    20-91";
$a[9]=">  120-40";
$a[10]=">  120-41";
$a[11]=">  020-41";
#  \D20\D     Esclude la 11
#  [^1-9]20\D comprende anche la 11:
#  ----
#  \d Indica una cifra   \D NON è una cifra
#  [1-9] Range 1..9   [^1-9] ESCLUSE CIFRE 1..9
my ($str) = @_;
	for ( my $i = 0; $i <= $#a; $i++ ){
		if ($a[$i]=~ /\D20\D/){
			print "$i , $a[$i] -> trovato\n";
		} else {
			print "$i , $a[$i] -> NON trovato\n";
		}
	}

 # [^1-9]20\D comprende anche la 11:
\D20\D :Questa gestisce il 20 in mezzo alla riga, ma non i casi in cui 
la riga inizia con 20 o finisce per 20. Va trasformata in: (^|\D)20(\D|$)
mentre l'altra [^1-9]20\D   poteva accettare rifiutava giustamente 120 
ma poteva accettare 1020 che è errato.
Questa dovrebbe essere corretta (aggiunto anche test sui lati):
(^|\D)[^1-9]*20(\D|$)
Nel commento del prog una descrizione del funzionamente delle regexp.
Il prog di prova è in perl che conosco, ma visto che le regex ci sono 
built-in anche per javascript non dovrebbe essere un problema trasformarlo.
#!/usr/bin/perl -w
$a[0]=">     1-107";
$a[1]=">    19-144";
$a[2]=">    19-145";
$a[3]=">    19-146";
$a[4]=">  200-60";
$a[5]=">  200-61";
$a[6]=">    20-87";
$a[7]=">    20-90";
$a[8]=">    20-91";
$a[9]=">  120-40";
$a[10]=">  120-41";
$a[11]=">  020-41";
$a[12]=">  0020-41";
$a[13]=">  01020-41";
$a[14]=">  01020-41";
$a[15]="00020-41";
$a[16]="00-20";
$a[17]="20-00";
$a[18]="pippo20 risulta valido";
# solo 20                 -> (^|\D)20(\D|$)
# (^|\D) Preceduto da qualcosa che sia l'inizio oppure
#        diverso da una cifra
# (\D|$) Seguito da qualcosa che sia la fine oppure
#        diverso da una cifra
#        Nota \D esclude solo le cifre pippo20 é buono
# anche sequenze di tipo 00020 -> (^|\D)[^1-9]*20(\D|$)
# [^1-9]* Preceduto da una qualsiasi serie di caratteri
#         che non contengano 1..9 . E' l'asterisco
#         che serve ad indicare 0 o più ripetizioni del
#         range 0..9
#         nota: "pippo20" è valido perchè ho escluso solo
#         i numeri da 1..9
my ($str) = @_;
	for ( my $i = 0; $i <= $#a; $i++ ){
		if ($a[$i]=~ /(^|\D)[^1-9]*20(\D|$)/){
 
			print "$i , $a[$i] -> trovato\n";
		} else {
			print "$i , $a[$i] -> NON trovato\n";
		}
	}
-OUTPUT per (^|\D)[^1-9]*20(\D|$)
0 , >     1-107 -> NON trovato
1 , >    19-144 -> NON trovato
2 , >    19-145 -> NON trovato
3 , >    19-146 -> NON trovato
4 , >  200-60 -> NON trovato
5 , >  200-61 -> NON trovato
6 , >    20-87 -> trovato
7 , >    20-90 -> trovato
8 , >    20-91 -> trovato
9 , >  120-40 -> NON trovato
10 , >  120-41 -> NON trovato
11 , >  020-41 -> trovato
12 , >  0020-41 -> trovato
13 , >  01020-41 -> NON trovato
14 , >  01020-41 -> NON trovato
15 , 00020-41 -> trovato
16 , 00-20 -> trovato
17 , 20-00 -> trovato
18 , pippo20 risulta valido -> trovato
-OUTPUT per (^|\D)20(\D|$)
0 , >     1-107 -> NON trovato
1 , >    19-144 -> NON trovato
2 , >    19-145 -> NON trovato
3 , >    19-146 -> NON trovato
4 , >  200-60 -> NON trovato
5 , >  200-61 -> NON trovato
6 , >    20-87 -> trovato
7 , >    20-90 -> trovato
8 , >    20-91 -> trovato
9 , >  120-40 -> NON trovato
10 , >  120-41 -> NON trovato
11 , >  020-41 -> NON trovato
12 , >  0020-41 -> NON trovato
13 , >  01020-41 -> NON trovato
14 , >  01020-41 -> NON trovato
15 , 00020-41 -> NON trovato
16 , 00-20 -> trovato
17 , 20-00 -> trovato
18 , pippo20 risulta valido -> trovato

 trasformarlo.
La trovi piů sopra:
MID Z-39-18.08.11$
10ccF1...@inwind.it
ed č anche possibile semplificarla:
alert(strHtml.replace(/( 20)*.( 20)*/g,'$1$2'));
con la risposta di ZER0:
MID 
4E4D4C58...@ID-171124.news.individual.net
    ..._skipped!_
-- 
    * b *
  *   y   *
*   Piero   *
#v+
-errare humanum est-
#v-