Как мне сделать массив.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 57

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

Это самый короткий.

haystack.join(' ').toLowerCase().split(' ').indexOf(needle.toLowerCase())

мне нужно было что-то подобное этому, где мне нужно было сравнить две строки с помощью 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();