在javascript数组中查找元素,哪个更快?

在javascript数组中查找元素,哪个更快?,javascript,performance,arrays,Javascript,Performance,Arrays,我是个书呆子,写了一个完整的程序,却不知道在数组中查找元素的简单方法 my_array.indexOf("find this value"); indexOf是否比存储一个数组中有多少个元素并在数组中循环直到找到所需的元素要好得多?我本可以简化我的代码很多 我试图通过使用多个数组和存储密钥使查找时间保持恒定。它使插入/删除变慢,因为我必须更新密钥 我应该用indexOf吗 感谢大多数情况下,您最好使用经过优化的本机函数,无论您提出什么解决方案。但是,除此之外,您还谈到了存储数组中元素的数量。当

我是个书呆子,写了一个完整的程序,却不知道在数组中查找元素的简单方法

my_array.indexOf("find this value");
indexOf是否比存储一个数组中有多少个元素并在数组中循环直到找到所需的元素要好得多?我本可以简化我的代码很多

我试图通过使用多个数组和存储密钥使查找时间保持恒定。它使插入/删除变慢,因为我必须更新密钥

我应该用indexOf吗


感谢

大多数情况下,您最好使用经过优化的本机函数,无论您提出什么解决方案。但是,除此之外,您还谈到了存储数组中元素的数量。当数组具有
.length
属性时,不确定为什么要这样做。

可以使用将值映射到数组索引。

Javascript基本上有两种类型的集合:数组和哈希映射。两者都有点特别。哈希映射只是一个具有命名属性的对象。键是用于直接访问值的字符串。下面是一个例子:

// create the hash map
var hashMap = {};
// add a value
var key = "John Dillinger";
hashMap[key] = "Criminal";
// retrieve the value
var stuff = hashMap[key];
Javascript数组具有双重功能。它们当然是数组,但也是堆栈。堆栈遵循“后进先出”规则。下面是一个数组和堆栈的示例:

// Array example
var anArray = []; // or: var anArray = new Array();
anArray[0] = "some value";
alert(anArray[0]); // pops up "some value"
// Stack example
var stack = [];
stack.push("first");
stack.push("second");
alert(stack.pop()); // pop up "second"
最后,对于一些问题,链表可能会派上用场。为此,您使用一个对象。大概是这样的:

var linkedList = {value: "stuff"};
linkedList.next = {value: "other"};
linkedList.next.next = {value: "yet another value"};
// Traverse the list
var node = linkedList;
while(node) {
  alert(node.value)
  node = node.next;
}

考虑到您描述的问题,我将使用哈希映射。只要记住为任何给定的问题选择正确的集合类型。

很可能
indexOf
方法的实现只是在数组上循环,直到找到请求的值为止,因为在一般情况下,这就是您所能做的。使用它可以清理您的代码,但不太可能使其更快。(搜索数组的数量很多,但有一定的限制和/或前期成本。)


您应该为作业使用正确的数据结构。数组用于顺序很重要的情况。如果你发现自己经常搜索它们,你可能应该使用散列来代替。散列是无序的,但查找是在固定时间内进行的(无搜索)。

本机函数应该更快,因为它是运行时引擎预编译的代码

然而,indexOf直到1.6版才实现,这意味着它在jscript/IE afaik中不起作用

但在这种情况下,我只想为它创建一个解决方案原型。本机函数通常是您的最佳选择


然而,在您的例子中,您似乎想要一个hashmap,正如Helgi所指出的,它在js中只是一个常规对象。

我已经实现了javascript hashmap,可以从中获取代码

代码如下:

/*
 =====================================================================
 @license MIT
 @author Lambder
 @copyright 2009 Lambder.
 @end
 =====================================================================
 */
var HashMap = function() {
  this.initialize();
}

HashMap.prototype = {
  hashkey_prefix: "<#HashMapHashkeyPerfix>",
  hashcode_field: "<#HashMapHashkeyPerfix>",

  initialize: function() {
    this.backing_hash = {};
    this.code = 0;
  },
  /*
   maps value to key returning previous assocciation
   */
  put: function(key, value) {
    var prev;
    if (key && value) {
      var hashCode = key[this.hashcode_field];
      if (hashCode) {
        prev = this.backing_hash[hashCode];
      } else {
        this.code += 1;
        hashCode = this.hashkey_prefix + this.code;
        key[this.hashcode_field] = hashCode;
      }
      this.backing_hash[hashCode] = value;
    }
    return prev;
  },
  /*
   returns value associated with given key
   */
  get: function(key) {
    var value;
    if (key) {
      var hashCode = key[this.hashcode_field];
      if (hashCode) {
        value = this.backing_hash[hashCode];
      }
    }
    return value;
  },
  /*
   deletes association by given key.
   Returns true if the assocciation existed, false otherwise
   */
  del: function(key) {
    var success = false;
    if (key) {
      var hashCode = key[this.hashcode_field];
      if (hashCode) {
        var prev = this.backing_hash[hashCode];
        this.backing_hash[hashCode] = undefined;
        if(prev !== undefined)
          success = true;
      }
    }
    return success;
  }
}

//// Usage

// creation

var my_map = new HashMap();

// insertion

var a_key = {};
var a_value = {struct: "structA"};
var b_key = {};
var b_value = {struct: "structB"};
var c_key = {};
var c_value = {struct: "structC"};

my_map.put(a_key, a_value);
my_map.put(b_key, b_value);
var prev_b = my_map.put(b_key, c_value);

// retrieval

if(my_map.get(a_key) !== a_value){
  throw("fail1")
}
if(my_map.get(b_key) !== c_value){
  throw("fail2")
}
if(prev_b !== b_value){
  throw("fail3")
}

// deletion

var a_existed = my_map.del(a_key);
var c_existed = my_map.del(c_key);
var a2_existed = my_map.del(a_key);

if(a_existed !== true){
  throw("fail4")
}
if(c_existed !== false){
  throw("fail5")
}
if(a2_existed !== false){
  throw("fail6")
}
/*
=====================================================================
@麻省理工学院执照
@作者兰德尔
@版权所有2009兰德尔。
@结束
=====================================================================
*/
var HashMap=函数(){
这是初始化();
}
HashMap.prototype={
hashkey_前缀:“”,
hashcode_字段:“”,
初始化:函数(){
this.backing_hash={};
该代码=0;
},
/*
将值映射到返回先前关联的键
*/
put:功能(键、值){
var-prev;
if(键和值){
var hashCode=key[this.hashCode_字段];
if(哈希代码){
prev=this.backing_hash[hashCode];
}否则{
此代码+=1;
hashCode=this.hashkey\u前缀+this.code;
key[this.hashcode_field]=hashcode;
}
this.backing_hash[hashCode]=值;
}
返回上一个;
},
/*
返回与给定键关联的值
*/
获取:函数(键){
var值;
如果(关键){
var hashCode=key[this.hashCode_字段];
if(哈希代码){
value=this.backing_hash[hashCode];
}
}
返回值;
},
/*
按给定键删除关联。
如果存在关联,则返回true,否则返回false
*/
del:功能(键){
var成功=false;
如果(关键){
var hashCode=key[this.hashCode_字段];
if(哈希代码){
var prev=this.backing_hash[hashCode];
this.backing_hash[hashCode]=未定义;
如果(上一个!==未定义)
成功=真实;
}
}
回归成功;
}
}
////用法
//创作
var my_map=new HashMap();
//插入
var a_key={};
var a_value={struct:“structA”};
var b_key={};
var b_value={struct:“structB”};
var c_key={};
var c_value={struct:“structC”};
my_map.put(一个_键,一个_值);
my_map.put(b_键,b_值);
var prev_b=我的映射。put(b_键,c_值);
//检索
如果(我的地图。获取(a_键)!==a_值){
投掷(“失败1”)
}
如果(我的地图获取(b_键)!==c_值){
投掷(“失败2”)
}
如果(上一个b!==b值){
投掷(“失败3”)
}
//删除
var a_existed=my_map.del(一个_键);
var c_existed=my_map.del(c_键);
var a2_existed=my_map.del(一个_键);
如果(a_存在!==真){
投掷(“失败4”)
}
如果(c_存在!==false){
投掷(“失败5”)
}
如果(a2_存在!==false){
投掷(“失败6”)
}
祝你好运,
Lambder

说JavaScript有“哈希映射”是错误的。事实上,JavaScript对象(当你说
var someName={};
--100%等同于
var someName=new Object;
)的行为在很多方面都类似于哈希表(映射),实际上,它们通常被实现为哈希表,人们应该把马叫做马,把物体叫做物体。