Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/xslt/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在javascript/node.js中迭代对象数组的有效方法_Javascript_Arrays_Sorting - Fatal编程技术网

在javascript/node.js中迭代对象数组的有效方法

在javascript/node.js中迭代对象数组的有效方法,javascript,arrays,sorting,Javascript,Arrays,Sorting,我定义了一个对象 var Person = function(name,age,group){ this.name = name, this.age = age, this.group = group } var ArrPerson = []; ArrPerson.push(new Person("john",12,"M1")); ArrPerson.push(new Person("sam",2,"M0")); 现在我需要一种有效的机制来识别对象数组是否包含特定的名称 我知道我们可以使用f

我定义了一个对象

var Person = function(name,age,group){
this.name = name,
this.age = age,
this.group = group
}

var ArrPerson = [];
ArrPerson.push(new Person("john",12,"M1"));
ArrPerson.push(new Person("sam",2,"M0"));
现在我需要一种有效的机制来识别对象数组是否包含特定的名称


我知道我们可以使用for循环和check对数组进行迭代。假设数组很大,还有其他有效的方法吗?

类似的方法应该可以

var Person=函数(姓名、年龄、组){
this.name=name,
这个年龄,
this.group=组
}
var ArrPerson=[];
ArrPerson.push(新人(“约翰”,12,“M1”);
ArrPerson.push(新人物(“sam”,2,“M0”);
for(var密钥输入人){
如果(ArrPerson[key].name=='john'){
//做点什么
警报(ArrPerson[key].name);
}

}
考虑到您想要检查所有,并且假设没有其他索引,那么问题仍然是O(n)。可以使用.filter()筛选并返回满足该条件的数组。或者,您可以使用其他一些数据结构根据您要搜索的内容编制索引

var Person=函数(姓名、年龄、组){
this.name=name,
这个年龄,
this.group=组
}
var ArrPerson=[];
ArrPerson.push(新人(“约翰”,12,“M1”);
ArrPerson.push(新人物(“sam”,2,“M0”);
函数findByName(arr,name){
返回arr.filter(函数(o){
返回o.name==name;
});
}
document.write(JSON.stringify(findByName(ArrPerson,john))
  • 使用ES5数组方法,如map、filter、reduce等
  • 使用forEach
  • 本机for循环
示例:filter、map、reduce等方法迭代数组中的每个项或对象

ArrPerson.filter(function(item){
       console.log(item)
   });
forEach
:也迭代数组中的每个项/对象

 ArrPerson.forEach(function(key,value){
     console.log(key);
     console.log(value)
  })
问题说的是巨大的数组,所以

native for loop
比上述任何一种方法都要快,缓存长度可以提高几毫秒(毫秒)

for(变量i=0,len=ArrPerson.length;i
您可以使用数组过滤器或查找方法

ArrPerson.find(p=>p.name=='john')
ArrPerson.filter(p=>p.name=='john')
find方法从开始搜索数组,并在找到一个匹配的元素时停止。在最坏的情况下,如果正在搜索的元素是数组中的最后一个元素或它不存在,则此方法将执行O(n)。这意味着此方法将执行n次检查(n为数组的长度),直到停止为止

filter方法总是执行O(n),因为每次它都会搜索整个数组以找到匹配的每个元素

尽管您可以通过创建新的数据结构(理论上)来加快速度。例如:

var hashmap = new Map();
var ArrPerson = [];
ArrPerson.push(new Person("john",12,"M1"));
hashmap.set("john",true);
此ES6映射将根据包含的名称保留整个数组的索引。如果要查看数组是否包含名称,可以执行以下操作:

hashmap.has('john')//true
这种方法可以实现O(1)。它只会在地图上检查一次,以查看数组中是否存在此名称。此外,您还可以跟踪映射内的数组索引:

var index = ArrPerson.push(new Person("john",12,"M1"));
var map_indexes = hashmap.get("john");
if(map_indexes){
  map_indexes.push(index-1);
  hashmap.set("john",map_indexes);
}else{
  hashmap.set("john",[index-1]);
}
map_indexes = hashmap.get("john"); //an array containing the ArrPerson indexes of the people named john
//ArrPerson[map_indexes[0]] => a person named john
//ArrPerson[map_indexes[1]] => another person named john ...
使用这种方法,不仅可以判断数组中是否有具有特定名称的人,还可以使用O(1)找到整个对象。 请注意,如果您需要其他条件,则此地图将仅按姓名为人员编制索引。您需要另一个地图。同时保持两个数据结构的同步也不容易(从数组中删除一个元素也应该从映射中删除,等等)


总之,在我们的示例中,速度的提高总是以牺牲其他东西、内存和代码复杂性为代价。

您是否只寻找
name
或其他属性?Thomas说得对-如果效率是首要标准,那么您不应该使用普通数组。如果您只有一个(未排序的)数组,除了迭代之外,你没什么别的办法了。常规的for循环将是最快的方法。此外,如果您只需要一个项目,您就可以打破循环。我需要首先检查名称,如果名称匹配,我需要检索年龄和组。ES5数组方法不是异步的。它们确实接受回调,但回调是同步调用的!
var index = ArrPerson.push(new Person("john",12,"M1"));
var map_indexes = hashmap.get("john");
if(map_indexes){
  map_indexes.push(index-1);
  hashmap.set("john",map_indexes);
}else{
  hashmap.set("john",[index-1]);
}
map_indexes = hashmap.get("john"); //an array containing the ArrPerson indexes of the people named john
//ArrPerson[map_indexes[0]] => a person named john
//ArrPerson[map_indexes[1]] => another person named john ...