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

时间:2009-05-30 20:29:42

标签: javascript performance arrays

我是一个菜鸟并且在不知道在阵列中找到元素的简单方法的情况下编写了整个程序...

my_array.indexOf("find this value");

indexOf比存储数组中有多少元素要好得多,并循环遍历数组直到找到所需的元素?我可以简化我的代码。

我尝试通过使用多个数组并存储密钥来使查找保持不变。它使插入/删除变慢,因为我必须更新密钥。

我应该刚使用indexOf吗?

由于

6 个答案:

答案 0 :(得分:5)

绝大多数情况下,您最好使用本机功能,该功能已针对您提出的任何解决方案进行了优化。然而,除此之外,你说了一些关于在数组中存储元素数量的事情。当数组具有.length属性时,不确定为什么会这样做。

答案 1 :(得分:2)

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

鉴于您描述的问题,我会使用哈希映射。请记住为任何给定的问题选择正确的集合类型。

答案 2 :(得分:1)

您可以使用hash table implementation in javascript将值映射到数组索引。

答案 3 :(得分:1)

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

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

但在这种情况下,我只想为它制作一个解决方法原型。本机功能通常是您的最佳选择。

但是,在你的情况下,似乎你想要一个hashmap,它在js中只是Helgi指出的常规对象。

答案 4 :(得分:0)

indexOf方法的实现可能只是循环遍历数组,直到找到所请求的值,因为在一般情况下,所有都可以执行。使用它会清理你的代码,但不太可能使它更快。 (搜索阵列有faster ways但它们带有某些限制和/或前期成本。)

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

答案 5 :(得分:-1)

我已经实现了javascript HashMap,可以从http://github.com/lambder/HashMapJS/tree/master

获取代码

以下是代码:

/*
 =====================================================================
 @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")
}

BonAppétit, Lambder