Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/385.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/angularjs/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 根据用户区域设置筛选字符串列表_Javascript_Angularjs_Internationalization - Fatal编程技术网

Javascript 根据用户区域设置筛选字符串列表

Javascript 根据用户区域设置筛选字符串列表,javascript,angularjs,internationalization,Javascript,Angularjs,Internationalization,在使用AngularJS 1.6进行JavaScript项目时,我有一个要筛选的字符串列表。例如,假设我的列表中包含阿尔波尔、库埃尼亚、尼多和图博 在用西班牙语过滤字符串时,如果我过滤“u”,我希望同时出现cigüeña和tubo,这对西班牙人来说是最自然的结果。然而,德语并非如此——u和ü是不同的字母,因此德国人不会希望看到cigüeña出现在名单上。因此,我正在寻找一种方法,使我的列表过滤了解用户的区域设置 我碰巧有一个包含很多变音符号的对象,例如: diacritics["á"] = "a

在使用AngularJS 1.6进行JavaScript项目时,我有一个要筛选的字符串列表。例如,假设我的列表中包含阿尔波尔、库埃尼亚、尼多和图博

在用西班牙语过滤字符串时,如果我过滤“u”,我希望同时出现cigüeña和tubo,这对西班牙人来说是最自然的结果。然而,德语并非如此——u和ü是不同的字母,因此德国人不会希望看到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);
}
上面的代码只是删除了所有的发音符号,所以我想让它知道用户的语言环境。因此,我将match()函数更改为:

function match(a) {
    if (diacritics[a] && a.localeCompare(diacritics[a] === 0) {
        return diacritics[a];
    }
    return a;
}
不幸的是,这不起作用。localeCompare函数在将“u”和“ü”与德语和西班牙语地区进行比较时返回相同的值,因此这里的答案并非如此。我已经看过了,并尝试了使用和灵敏度选项,但它们在这里似乎没有多大帮助


我如何调整我的代码使其工作?是否有任何库可以为我正确处理此问题?

您可能正在寻找ECMA 6库。这将允许您根据区域设置调整排序顺序,例如:

// 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
敏感度:'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

然后,您可以在填充UI小部件之前将列表按正确的顺序排序。

我将通过
导航器
()直接从浏览器获取用户的区域设置,该对象表示用户代理:

var language = navigator.language;
这将分配
语言
用户浏览器的区域设置代码,在我的例子中是
en-US
。我发现找到地区代码有助于测试世界其他地区

My
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);
}
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
注意带有
Intl.Collator
()的行。这一行将变音符号与变音符号的规范化字母进行比较,并检查给定语言的字母表是否存在位置差异。因此:

/* 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
时,它才会返回true,这表明该语言字母表中的字母没有位置差异,这意味着可以安全地替换

下面是对
strFromLocale
函数的一些测试:

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);
}
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

可悲的是,这不起作用。这与我在localeCompare()中提到的基本相同:当比较“u”和“u”时,西班牙语和德语的结果是相同的。Collator和localeCompare()都会出现这种情况,这并不奇怪,因为它们是同一个API的一部分。在阅读了Cole的回答后,我意识到我的方法和您的解决方案都缺少的是同时使用usage=“search”和sensition=“base”。一旦我们这样做了,整理者就会意识到西班牙语和德语的“u”和“u”之间的区别,如果我们不使用“用法”,这是不会发生的。我认为你的最后一个片段中有一个小错误。我认为“location”变量应该称为“language”。除此之外,它是完美的@哎呀,现在修好了