2015-01-09 5 views
6

Ich habe eine Webseite, wo, wenn etwas im Suchfeld eingegeben wurde, es dann durch eine Datei für diesen Wert iteriert, so dass Suche/Suche Groß-und Kleinschreibung nicht berücksichtigt . Die Case-Sensitivität muss in der Datei verbleiben, aber zu Vergleichszwecken ignoriert sie den Fall. so zur Zeit i Strich Befehl bin mit:Wie man _.where() im Unterstrich verwendet, um Werte unabhängig vom Fall zu vergleichen

arr=_.where(arr,filter); 

aber den 2-Arrays arr und filter - i sie benötigen, unabhängig von Fall verglichen/verwendet werden, um das Endergebnis arr Ergebnisse enthalten die Mischung aus Groß- und Kleinschreibung aber stimmt Wert (en) in arr überein. kann jemand bitte helfen?

+1

Warum auf demselben Fall in der Filterfunktion nicht konvertieren? –

Antwort

1

Leider JS ist nicht groß, wenn es um internationalisierte Groß- und Kleinschreibung String-Vergleich kommt. Wenn Sie nur wenn auf ASCII kleben, ist die Lösung recht einfach (mit filter aber nicht where):

function getMatches(query, arr) { 
    var lowerQuery = query.toLowerCase(); 
    return _.filter(arr, function(term) { 
    return term.toLowerCase() == lowerQuery; 
    }); 
} 

Oder wenn Sie wollen alles vorauszuberechnen, weil Sie viele Anfragen in derselben zu machen erwarten JS session:

var index = _.groupBy(arr, function(term) { return term.toLowerCase(); }); 

// Post-process index to reduce memory footprint by turning redundant values to nulls 
// (which take up less memory than arrays with a string in them). 
index = _.object(_.map(index, function(terms, key) { 
    return [key, (terms.length == 1 && terms[0].toLowerCase() == terms[0] ? null : terms)]; 
})); 

function getMatches(query) { 
    var lowerQuery = query.toLowerCase(); 
    return (lowerQuery in index ? index[lowerQuery] || lowerQuery : []); 
} 

Dieses zweite Verfahren hat den Vorteil, nur die Berechnung toLowercase() die minimale Anzahl, wie oft und minimaler Datenspeicherung wegen des Nachbearbeitungsschrittes.

Here's a JSFiddle for both

2

Try filter statt mit:

var filter = ["Apple", "bANAna", "orange"]; 
 
var arr = ["apPle", "ORANGE"]; 
 

 
// make filter lower case once  
 
var filterLower = _.invoke(filter, "toLowerCase"); 
 

 
var arr2 = _.filter(arr, function(v) { 
 
    // make entry lower case and see if it is in filterLower 
 
    return _.contains(filterLower, v.toLowerCase()); 
 
}); 
 

 
console.dir(arr2);
<script src="http://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.4.4/underscore-min.js"></script>

+0

Während möglicherweise mehr performant, wenn Sie eine Menge von Abfragen durchführen (insofern es nur 'n + q' 'toLowerCase' Aufrufe statt" n * q "mit meiner Lösung, wo' n' ist die Anzahl der Begriffe und 'q' ist die Anzahl der Abfragen), es sollte angemerkt werden, dass diese Lösung den doppelten Speicher benötigt, was problematisch sein kann, wenn der Begriff Liste lang ist. Auch, Rhumborl, leichte Änderung, aber ich denke, OP versucht nur 1 Abfrage auf einmal zu suchen. Ich glaube, sie haben es falsch verstanden, ein Array "filter" zu nennen. – 0x24a537r9

+0

Ich denke auch, dass dies leistungsfähiger wäre (konstante Nachschlagezeiten), wobei ein "Objekt" mit den Kleinbuchstaben verwendet wird, da die Schlüssel auf Arrays der ursprünglichen Strings verweisen, auf die sie verweisen. Sie könnten dann auch den Platzbedarf optimieren, indem Sie die Wert-Arrays für einzelne, bereits kleingeschriebene Wörter durch einen kompakteren Typ wie "true" ersetzen und genau wissen, wie man das interpretiert. – 0x24a537r9