繁体   English   中英

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

[英]Which is faster for finding element in javascript array?

我是一个菜鸟,在不知道在数组中查找元素的简单方法的情况下编写了整个程序。

my_array.indexOf("find this value");

indexOf比存储数组中有多少个元素并遍历数组直到找到所需元素好得多吗? 我本可以简化很多代码。

我试图通过使用多个数组并存储键使查询保持恒定的时间。 尽管我必须更新密钥,但这会使插入/删除速度变慢。

我应该刚刚使用indexOf吗?

谢谢

在绝大多数情况下,您可以使用针对您提出的任何解决方案进行了优化的本机功能。 但是除此之外,您还说了一些有关在数组中存储元素数量的信息。 不知道为什么数组具有.length属性时为什么.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;
}

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

您可以在JavaScript中使用哈希表实现将值映射到数组索引。

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

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

但是在这种情况下,我只是为它设计一种解决方法。 本机函数通常是您的最佳选择。

但是,就您的情况而言,您似乎想要一个哈希表,正如Helgi指出的那样,在js中这只是一个常规对象。

indexOf方法的实现很可能会遍历数组,直到找到所需的值为止,因为在一般情况下,这就是您能做的。 使用它可以清理您的代码,但不太可能使其更快。 (有更快的搜索数组的方法 ,但它们具有某些限制和/或前期成本。)

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

我已经实现了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")
}

邦德·阿佩蒂特(Lambder)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM