Как мне сделать массив.indexOf() без учета регистра?
Я делаю кусок кода на сайт, который будет иметь список имена в массив и выбрать случайное имя, я хочу добавить функцию, которая позволит пользователю добавить или удалить имя из массива. У меня все эти функции, но при удалении имени, пользователь должен ввести имя на случай, если в массиве. Я попытался сделать так, чтобы это было нечувствительно к регистру, что я делаю неправильно?
<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>
10 ответов:
простым способом было бы иметь временный массив, который содержит все имена в верхнем регистре. Затем вы можете сравнить пользовательский ввод. Так что ваш код может стать чем-то вроде этого:
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(" | "); } }
надеюсь, что это поможет решить вашу проблему.
ES2015 findIndex:
var array = ['I', 'hAve', 'theSe', 'ITEMs'], query = 'these', result = array.findIndex(item => query.toLowerCase() === item.toLowerCase()); console.log(result); // 2
в ECMA-262, 5-е издание, вы можете использовать
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
наиболее элегантным решением было бы сначала преобразовать массив в строку, а затем выполнить сравнение без учета регистра. Например:
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 }
вероятно, лучше всего создать свой собственный
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'));
или даже
'use strict'; var customIndexOf = function(array, searchElement, fromIndex) { return array.map(function(value) { return value.toLowerCase(); }).indexOf(searchElement.toLowerCase(), fromIndex); }; var names = [ 'John', 'Anne', 'Brian' ]; console.log(customIndexOf(names, 'aNnE'));
вы также можете добавить дополнительные проверки, чтобы убедиться, что каждый элемент в массиве на самом деле
String
иsearchElement
тоже на самом делеString
тоже. Если предварительно в ES5, затем загрузить соответствующее прокладки
это возможно с помощью метода map. Например, см. ниже код
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 } }
Поверните массив в строку, разделенную разделителем, поверните эту строку в нижний регистр, а затем разделите строку обратно в массив тем же разделителем:
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:'); }
мне нужно было что-то подобное этому, где мне нужно было сравнить две строки с помощью
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 (небольшое изменение к этому использовало символ тильды в качестве разделителя в случае, если любое из значений массива содержало пробелы)
function compare(l1: any[], l2: any[], ignoreCase = true): boolean { return (ignoreCase ? l1.join('~').toLowerCase().split('~') : l1).indexOf((ignoreCase ? l2.join('~').toLowerCase().split('~') : l2)); }
снова надеюсь, что это помогает.
вы не можете сделать его нечувствительным к регистру. Я бы использовал объект вместо того, чтобы содержать набор имен:
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();