2017-11-16 40 views
12

पर आधारित स्ट्रिंग्स की एक सूची फ़िल्टर करना AngularJS 1.6 के साथ एक जावास्क्रिप्ट प्रोजेक्ट पर काम करते समय, मेरे पास स्ट्रिंग्स की एक सूची है जिसे मैं फ़िल्टर करना चाहता हूं। उदाहरण के लिए, मान लेते हैं मेरी सूची Arbol, cigüeña, nido और ट्यूब शामिल हैं।उपयोगकर्ता लोकेल

जब स्पेनिश में तार को छानने, अगर मैं "यू" के लिए फ़िल्टर, मैं प्रकट करने के लिए है, जो एक स्पेनी के लिए सबसे अधिक प्राकृतिक परिणाम होगा दोनों cigüeña और ट्यूब उम्मीद थी। हालांकि, जर्मन में यह मामला नहीं है - आप और ü अलग-अलग अक्षर हैं और इस प्रकार एक जर्मन सूची में सिगुएना देखना नहीं चाहेगा। तो मैं अपनी सूची को उपयोगकर्ता के लोकेल के बारे में जागरूक करने के लिए एक तरीका ढूंढ रहा हूं।

मैंने किसी चीज़ विशेषक के बहुत सारे हैं, जैसे कि युक्त करने के लिए होती हैं:

diacritics["á"] = "a"; 
diacritics["ü"] = "u"; 
// and so on... 

इस तरह क्या मेरी छानने कोड दिखाई देता है:

function matches(word, search) { 
    var cleanWord = removeDiacritics(word.toLowerCase()); 
    var cleanSearch = removeDiacritics(search.toLowerCase()); 
    return cleanWord.indexOf(cleanSearch) > -1; 
} 

function removeDiacritics(word) { 
    function match(a) { 
     return diacritics[a] || a; 
    } 
    return text.replace(/[^\u0000-\u007E]/g, match); 
} 

ऊपर कोड बस सभी विशेषक निकाल देता है, तो मैंने इसे उपयोगकर्ता के लोकेल के बारे में जागरूक करने के लिए सोचा। इस प्रकार, मैंने मैच() फ़ंक्शन को इस पर बदल दिया:

function match(a) { 
    if (diacritics[a] && a.localeCompare(diacritics[a] === 0) { 
     return diacritics[a]; 
    } 
    return a; 
} 

दुर्भाग्यवश, यह काम नहीं करता है। लोकेल कॉम्पैयर फ़ंक्शन जर्मन और स्पैनिश लोकेशंस के साथ "यू" और "ü" की तुलना करते समय समान मूल्य देता है, इसलिए यह यहां जवाब नहीं था। मैं reference for the localeCompare method पर गया हूं और उपयोग और संवेदनशीलता विकल्पों का प्रयास किया है, लेकिन वे यहां बहुत मदद नहीं कर रहे हैं।

इस काम के लिए मैं अपने कोड को कैसे बदल सकता हूं? क्या कोई पुस्तकालय है जो इसे मेरे लिए ठीक से संभाल सकता है?

उत्तर

3

मैं उपयोगकर्ता किसी भी स्थान navigator (src) के माध्यम से उपयोगकर्ता एजेंट का प्रतिनिधित्व ब्राउज़र से सीधे हो रही, एक वस्तु के बारे में जाना चाहते हैं:

var language = navigator.language; 

यह language आवंटित करेगा उपयोगकर्ता के ब्राउज़र की स्थान कोड, में मेरा मामला en-US। मुझे this site दुनिया के अन्य क्षेत्रों का परीक्षण करने के लिए लोकेल कोड खोजने के लिए उपयोगी पाया गया।

मेरे strFromLocale समारोह अपने removeDiacritics समारोह के बराबर है:

function strFromLocale(str) { 
    function match(letter) { 
     function letterMatch(letter, normalizedLetter) { 
      var location = new Intl.Collator(language, {usage: 'search', sensitivity: 'base' }).compare(letter, normalizedLetter); 
      return (location == 0) 
     } 
     normalizedLetter = letter.normalize('NFD').replace(/[\u0300-\u036f]/gi, "") 
     if (letterMatch(letter, normalizedLetter)) { 
      return normalizedLetter; 
     } else { 
      return letter; 
     } 
    } 
    return str.replace(/[^\u0000-\u007E]/g, match); 
} 

नोट Intl.Collator (src) के साथ लाइन।यह रेखा डायक्रिटिक की सामान्यीकृत अक्षर के साथ डायक्रिटिक की तुलना करती है और स्थितित्मक मतभेदों के लिए दी गई भाषा के वर्णमाला की जांच करती है। इसलिए:

/* English */ 
new Intl.Collator('en-US', {usage: 'search', sensitivity: 'base' }).compare('u', 'ü'); 
>>> 0 

/* Swedish */ 
new Intl.Collator('sv', {usage: 'search', sensitivity: 'base' }).compare('u', 'ü'); 
>>> -1 

/* German */ 
new Intl.Collator('de', {usage: 'search', sensitivity: 'base' }).compare('u', 'ü'); 
>>> -1 

आप letterMatch समारोह में देख सकते हैं, यह सच रिटर्न अगर और सिर्फ़ अगर Intl.Collator का परिणाम 0 है, यह दर्शाता है कि वहाँ कोई स्थितीय यह जिसका अर्थ है कि भाषा की वर्णमाला के भीतर पत्र के मतभेद हैं कि प्रतिस्थापित करने के लिए सुरक्षित है।

इसी के साथ

, यहाँ strFromLocale समारोह के कुछ परीक्षण कर रहे हैं:

var language = navigator.language; // en-US 
strFromLocale("cigüeña"); 
>>> ciguena 

var language = 'sv' // Swedish 
strFromLocale("cigüeña"); 
>>> cigüena 

var language = 'de' // German 
strFromLocale("cigüeña"); 
>>> cigüena 

var language = 'es-mx' // Spanish - Mexico 
strFromLocale("cigüeña"); 
>>> cigueña 
+1

मुझे लगता है कि आपके आखिरी स्निपेट में एक छोटी सी गलती है। मुझे लगता है कि "स्थान" चर को "भाषा" कहा जाना चाहिए। इसके अलावा, यह सही है! – unpollito

+1

@unpollito ओह, यह अभी तय है – Cole

1

आप शायद ईसीएमए 6 Intl लाइब्रेरी की तलाश में हैं। यह तो आप स्थान, उदा, के आधार पर सॉर्ट क्रम .: व्यवस्थित कर सकते हैं

// in German, ä sorts with a 
console.log(new Intl.Collator('de').compare('ä', 'z')); 
// → a negative value 

// in Swedish, ä sorts after z 
console.log(new Intl.Collator('sv').compare('ä', 'z')); 
// → a positive value 

sensitivity: 'base' विकल्प स्वचालित रूप से तरह साथ/विशेषक के बिना।

// in German, ä has a as the base letter 
console.log(new Intl.Collator('de', { sensitivity: 'base' }).compare('ä', 'a')); 
// → 0 

// in Swedish, ä and a are separate base letters 
console.log(new Intl.Collator('sv', { sensitivity: 'base' }).compare('ä', 'a')); 
// → a positive value 

फिर आप अपने यूआई विजेट को पॉप्युलेट करने से पहले अपनी सूची को सही क्रम में सॉर्ट कर सकते हैं।

+0

दुःख की बात है कि काम नहीं कर रहा। यह अनिवार्य रूप से वही है जो मैंने लोकेल कॉम्पारे() बिट में उल्लेख किया है: "यू" और "ü" की तुलना करते समय, परिणाम स्पेनिश और जर्मन में समान होते हैं। यह कॉललेटर और लोकेल कॉम्पारे() दोनों के साथ होता है, जो असुरक्षित है क्योंकि वे एक ही एपीआई का हिस्सा हैं। – unpollito

+0

कोल के जवाब पढ़ने के बाद, मुझे एहसास हुआ कि मेरे दृष्टिकोण और आपके समाधान दोनों में क्या लापता था, साथ ही उपयोग = "खोज" और संवेदनशीलता = "आधार" का उपयोग करना था। एक बार जब हम ऐसा करते हैं, तो कॉलर स्पेनिश और जर्मन के लिए "यू" और "ü" के बीच का अंतर महसूस कर सकता है, जो तब नहीं होता है जब हम "उपयोग" छोड़ देते हैं। – unpollito

संबंधित मुद्दे