通过对象的id在javascript数组中查找并移动对象

4
我有两个对象数组。每个对象都有一个Id属性。现在,如果我有一个只包含Ids的第三个数组,找到基于这些Ids从array1中的对象并将它们移动到array2的更好和更快的方法是什么。
感谢您的回答。
示例代码:
Person = function(id, fn, ln) {
  this.id = id,
  this.firstName = fn,
  this.lastName = ln
}

array1 = new Array();
// add 500 new Person objects to this array

array2 = new Array();
// add some other new Person objects to this array

function moveArrayItems(ids) {
  // ids is an array of ids e.g. [1,2,3,4,5,6,...]
  // Now I want to find all the person objects from array1 whose ids 
  // match with the ids array passed into this method. Then move them to array2.
  // What is the best way to achive this?
}

... = new Array(); 的调用是不必要的。在Javascript中创建数组的最佳方法是使用数组字面量:... = []; - Matt Ball
4个回答

9
如果你真的有每个数组中超过500个对象,你最好使用哈希表存储这些对象,按照id进行键值对映射:
var people = {
              1: {id:1, name:"George Washington"},
              2: {id:2, name:"John Adams"},
              3: {id:3, name:"Thomas Jefferson"},  // ...
             } 

var people2 = {}

现在通过ID移动元素已经变得非常简单(而且速度大大提高):

function moveArrayItems(ids) {
    var i,id;
    for (i=0; i<ids.length; i++){
        id = ids[i];
        if (people1[id]) {
            people2[id] = people1[id];
            delete people1[id];
        }
    }
}

我正在从JSON中获取对象,它是一个带有索引从o到n的数组。我可以循环遍历它,并使用ID构建新的对象/数组与索引一起使用。除了循环之外,还有其他更好的方法吗? - Bharat
如果你的代码主要是进行操作,那么将数组预处理成哈希表所需的O(n)成本是值得的。 - justkt

1

好问题。它实际上让我回顾了基础知识。JS数组的关键是它是稀疏的。你可以创建一个数组并为任何索引(例如:10和23)分配值。基于这个事实。

array1 = new Array();

array1[person1.id] = person1;
array1[person2.id] = person2;
.... goes till N

function moveArrayItems(ids) {
  for(index in ids) {
      array2.push(array1[ids[index]]);
      delete array1[ids[index]];
  }
}

注意:我假设Person.id是一个整数且小于2^32-1。如果id大于或为浮点数,请参考JS文档。JS数组实现不是一个连续的块,所以不要认为将值分配给索引12345需要12345个连续的内存块。


这个答案的速度是否与Triptych的答案类似?我认为是的,因为JavaScript对象就像哈希表,你可以分配字段名,它将成为该条目的键。我想确认一下,以确保速度与其他答案相同。 - Bharat
如果两者以相同的速度运行,我也不会感到惊讶。JS数组就像哈希表一样,除了键必须是非负整数。使用数组可能比普通对象稍快一些。浏览器知道它是一个数组,并可能对其进行迭代优化。在对象技术中,它对于浏览器来说是一个对象,对于您来说是一个哈希表。您可以对这两个答案进行秒表类型的分析并决定。如果您能等一段时间,我会尝试进行一些分析并在此处发布。 - Aravindan R

0

以下是一些快速的未经测试的伪代码。这个算法的时间复杂度是O(n^2),所以可能不是最好的。

  function moveArrayItems(ids) {
    // ids is an array of ids e.g. [1,2,3,4,5,6,...]
    //Now I want to find all the person objects from array1 whose ids match with the ids  array passed into this method. Then move them to array2.
    //What is the best way to achive this?
    for(i = 0;i < ids.length;i++){ 
      var found = false;
      var j = 0;
      while(!found && j < array1.length){
          if(array1[j].id = ids[i]){
             array2.push(array1[j]);
             found = true;
          }              
          j++;
      }
    }
 }

0

首先是一个小函数,由John Resig编写

// Array Remove - By John Resig (MIT Licensed)
Array.prototype.remove = function(from, to) {
  var rest = this.slice((to || from) + 1 || this.length);
  this.length = from < 0 ? this.length + from : from;
  return this.push.apply(this, rest);
};

然后,合并文森特的解决方案

function moveArrayItems(ids) 
{   
  // ids is an array of ids e.g. [1,2,3,4,5,6,...]   
  // Now I want to find all the person objects from array1 
  // whose ids match with the ids  array passed into 
  // this method. Then move them to array2.   
  // What is the best way to achive this?   

  for(i = 0; i < ids.length; i++)
  {    
    var found = false;   
    var j = 0;   
    while(!found && j < array1.length)
    {   
      if(array1[j].id = ids[i])
      {   
         array2.push(array1[j]);   
         array1.remove(i);
         found = true;   
      }                 
      j++;   
    }   
  }   
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接