Как сделать Array.indexOf() нечувствительным к регистру?
Я делаю кусок кода для сайта, который будет иметь список имен в массиве и выбрать случайное имя, я хочу добавить функцию, которая позволит пользователю добавлять или удалять имя из массива. У меня есть все эти функции, но при удалении имени пользователь должен ввести имя в соответствии с Case в массиве. Я попытался сделать так, чтобы это было нечувствительным к регистру, что я делаю неправильно?
<html>
<!--Other code uneeded for this question-->
<p id="canidates"></p>
<body>
<input type="text" id="delname" /><button onclick="delName()">Remove Name from List</button>
<script>
//Array of names
var names = [];
//Other code uneeded for this question
//List of Canidates
document.getElementById('canidates').innerHTML =
"<strong>List of Canidates:</strong> " + names.join(" | ");
//Other code uneeded for this question
//Remove name from Array
function delName() {
var dnameVal = document.getElementById('delname').value;
var pos = names.indexOf(dnameVal);
var namepos = names[pos]
var posstr = namepos.toUpperCase();
var dup = dnameVal.toUpperCase();
if(dup != posstr) {
alert("Not a valid name");
}
else {
names.splice(pos, 1);
document.getElementById('canidates').innerHTML =
"<strong>List of Canidates:</strong> " + names.join(" | ");
}
}
</script>
</body>
</html>
Ответы
Ответ 1
Легким способом было бы иметь временный массив, содержащий все имена в верхнем регистре. Затем вы можете сравнить пользовательский ввод. Таким образом, ваш код может стать следующим:
function delName() {
var dnameVal = document.getElementById('delname').value;
var upperCaseNames = names.map(function(value) {
return value.toUpperCase();
});
var pos = upperCaseNames.indexOf(dnameVal.toUpperCase());
if(pos === -1) {
alert("Not a valid name");
}
else {
names.splice(pos, 1);
document.getElementById('canidates').innerHTML =
"<strong>List of Canidates:</strong> " + names.join(" | ");
}
}
Надеюсь, это поможет решить вашу проблему.
Ответ 2
var array = ['I', 'hAve', 'theSe', 'ITEMs'],
query = 'these',
result = array.findIndex(item => query.toLowerCase() === item.toLowerCase());
console.log(result); // 2
Ответ 3
В ECMA-262, 5th edition, вы можете использовать Array.prototype.some
для этого.
var array = [ 'I', 'hAve', 'theSe', 'ITEMs' ];
var query = 'these'.toLowerCase();
var index = -1;
array.some(function(element, i) {
if (query === element.toLowerCase()) {
index = i;
return true;
}
});
// Result: index = 2
Ответ 4
Наиболее элегантным решением было бы преобразование массива в строку сначала, а затем сравнение без учета регистра. Например:
var needle = "PearS"
var haystack = ["Apple", "banNnas", "pEArs"];
var stricmp = haystack.toString().toLowerCase(); // returns
// "apple,bananas,pears"
if (stricmp.indexOf(needle.toLowerCase()) > -1) {
// the search term was found in the array
} else {
// the search term was not found in the array
}
Ответ 5
Вероятно, лучше всего создать свой собственный метод indexOf
, что-то вроде этого.
'use strict';
var customIndexOf = function(arrayLike, searchElement) {
var object = Object(arrayLike);
var length = object.length >>> 0;
var fromIndex = arguments.length > 2 ? arguments[2] >> 0 : 0;
if (length < 1 || typeof searchElement !== 'string' || fromIndex >= length) {
return -1;
}
if (fromIndex < 0) {
fromIndex = Math.max(length - Math.abs(fromIndex), 0);
}
var search = searchElement.toLowerCase();
for (var index = fromIndex; index < length; index += 1) {
if (index in object) {
var item = object[index];
if (typeof item === 'string' && search === item.toLowerCase()) {
return index;
}
}
}
return -1;
};
var names = [
'John',
'Anne',
'Brian'
];
console.log(customIndexOf(names, 'aNnE'));
Ответ 6
Возможно использование методом карты. Например, см. Ниже код
var _name = ['prasho','abraham','sam','anna']
var _list = [{name:'prasho'},{name:'Gorge'}];
for(var i=0;i<_list.length;i++)
{
if(_name.map(function (c) {
return c.toLowerCase();
}).indexOf(_list[i].name.toLowerCase()) != -1) {
//do what ever
}else{
//do what ever
}
}
Дополнительная информация
Ответ 7
Поверните массив в строку, разделенную разделителем, измените эту строчку в нижнем регистре и затем разделите строку обратно на массив одним и тем же разделителем:
function findIt(arr, find, del) {
if (!del) { del = '_//_'; }
arr = arr.join(del).toLowerCase().split(del);
return arr.indexOf(find.toLowerCase());
}
var arr = ['Tom Riddle', 'Ron Weasley', 'Harry Potter', 'Hermione Granger'];
var find = 'HaRrY PoTtEr';
var index = findIt(arr, find);
if (~index) {
alert('Found ' + arr[index] + '! :D');
} else {
alert('Did not find it. D:');
}
Ответ 8
Это самый короткий.
haystack.join(' ').toLowerCase().split(' ').indexOf(needle.toLowerCase())
Ответ 9
Мне нужно было что-то похожее на это, где мне нужно было сравнить две строки, используя includes
, и мне нужно было иметь возможность поддерживать поиск без учета регистра, поэтому я написал следующую небольшую функцию
function compare(l1: string, l2: string, ignoreCase = true): boolean {
return (ignoreCase ? l1.toLowerCase() : l1).includes((ignoreCase ? l2.toLowerCase() : l2));
}
Тот же принцип может применяться к indexOf
, как показано ниже
function indexOf(l1: string, l2: string, ignoreCase = true): number {
return (ignoreCase ? l1.toLowerCase() : l1).indexOf((ignoreCase ? l2.toLowerCase() : l2));
}
Я знаю, что это не совсем Array.indexOf
, но надеюсь, что это поможет кому-то, если он наткнется на этот пост в своих путешествиях.
Чтобы ответить на вопрос ops, вы можете применить его аналогично к массиву, объединенному с этим ответом из @ULIT JAIDEE (небольшое изменение в этом заключалось в использовании символа тильды в качестве разделителя в case любое из значений массива содержит пробелы)
function compare(l1: any[], l2: any[], ignoreCase = true): boolean {
return (ignoreCase ? l1.join('~').toLowerCase().split('~') : l1).indexOf((ignoreCase ? l2.join('~').toLowerCase().split('~') : l2));
}
И снова надеюсь, что это поможет.
Ответ 10
found = myArray.find(key => key.toUpperCase() === searchString.toUpperCase()) != undefined;
Пример:
myArray = ['An', 'aRRay', 'oF', 'StringS'];
searchString = 'array';
found = myArray.find(key => key.toUpperCase() === searchString.toUpperCase()) != undefined;
if (found ) {
// The array contains the search string
}
else {
// Search string not found
}
Примечание. Массив не может содержать значение undefined
.
Ответ 11
Вы не можете сделать это без учета регистра. Вместо этого я бы использовал объект для хранения набора имен:
function Names() {
this.names = {};
this.getKey = function(name) {
return name.toLowerCase();
}
this.add = function(name) {
this.names[this.getKey(name)] = name;
}
this.remove = function(name) {
var key = this.getKey(name);
if (key in this.names) {
delete this.names[key];
} else {
throw Error('Name does not exist');
}
}
this.toString = function() {
var names = [];
for (var key in this.names) {
names.push(this.names[key]);
}
return names.join(' | ');
}
}
var names = new Names();
function update() {
document.getElementById('canidates').innerHTML = '<strong>List of Canidates:</strong> ' + names;
}
function deleteName() {
var name = document.getElementById('delname').value;
try {
names.remove(name);
update();
} catch {
alert('Not a valid name');
}
}
update();