如何使Array.indexOf()不区分大小写?


76

我正在为网站编写一段代码,该网站将在数组中包含一个名称列表,并选择一个随机名称,我想添加一个功能,该功能将允许用户在数组中添加或删除名称。我具有所有这些功能,但是删除名称时,用户必须键入名称以匹配数组中的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>

3
您不能使.indexOf()大小写不敏感。您可以规范数组和搜索项之间的大小写。您似乎正在搜索然后转换大小写,所以这对您没有帮助。你可以做.toUpperCase()dnameVal搜索之前,但如果所有的名字也是大写的,只会工作。
Cookie怪物

3
作为重复项链接到的问题是关于字符串中不区分大小写的搜索,而这个问题是关于数组中不区分大小写的搜索。
Robby Cornelissen 2014年

3
在这个问题中,OP正在使用Array.indexOf,指向的答案(以及为什么关闭)正在使用String.indexOf
Xotic750 2014年

Answers:


28

一种简单的方法是拥有一个包含所有大写名称的临时数组。然后,您可以比较用户输入。因此,您的代码可能会变成这样:

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
每个人都认真地考虑使用自定义indexOf实现...尽管我喜欢使用Array.prototype.some的user113215答案……
Ralph

为什么还要创建一个全部大写的数组?为什么不将数组直接转换为已经可以区分大小写的内容呢?像字符串吗?
DMCoding '16

68

ES2015 findIndex

var array = ['I', 'hAve', 'theSe', 'ITEMs'],
    indexOf = (arr, q) => arr.findIndex(item => q.toLowerCase() === item.toLowerCase());

console.log(  indexOf(array, 'i')      ) // 0
console.log(  indexOf(array, 'these')  ) // 2
console.log(  indexOf(array, 'items')  ) // 3


9
Internet Explorer不支持。
V Setyawan

1
@Vznz-如果您正在使用Babel或类似的东西,它将自动转换它,这是当今非常普遍的做法。
vsync

2
@VSetyawan谁在乎?该浏览器早该消失了!
涡流

31

在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

1
如果更改queryquery.toLowerCase(),这是最佳答案if
谢尔比·L·莫里斯

3
@sxnine同样,如果不能保证不能保证它是一个字符串,您实际上会使用String(element).toLowerCase()它。我编辑了帖子,以将其添加到循环之外以进行演示。它不属于循环内部,因为它会在每次迭代时发生。elementquery
quietmint 2014年

10

最优雅的解决方案是先将数组转换为字符串,然后进行不区分大小写的比较。例如:

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
}

4
我希望needle永远不要包含逗号。
2013年

1
子字符串呢?根据这needle='p'也将是haystack
Gio

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

甚至

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

您可能还需要添加更多检查,以确保数组中的每个元素实际上都是a,String并且searchElement实际上也是a String。如果是ES5之前的版本,请加载适当的垫片


2

您可以使用Array.prototype.find()

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作为值。


1

通过地图方法可以使用。例如看下面的代码

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

更多信息


0

将数组转换为由定界符分隔的字符串,将字符串转换为小写,然后使用相同的定界符将字符串拆分回数组:

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


0

这是最短的。

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

1
希望您的干草堆中永远不会包含带空格的字符串。
牧草

0

我需要类似的东西,我需要使用两个字符串进行比较,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·贾迪(在案件的细微变化,以本是使用蒂尔达为分隔符的任何值包含空格的数组)

function compare(l1: any[], l2: any[], ignoreCase = true): boolean {
  return (ignoreCase ? l1.join('~').toLowerCase().split('~') : l1).indexOf((ignoreCase ? l2.join('~').toLowerCase().split('~') : l2));
}

再次希望这会有所帮助。


0
// unique only, removes latter occurrences    
array.filter((v, i, a) => a.findIndex(j => v.toLowerCase() === j.toLowerCase()) === i);

-2

您不能使其不区分大小写。我会改用一个对象来保存一组名称:

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();
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.