如果属性与另一个数组匹配,则检索数组中的对象

Posted

技术标签:

【中文标题】如果属性与另一个数组匹配,则检索数组中的对象【英文标题】:Retrieve objects in array if property matches another array 【发布时间】:2019-04-14 19:25:47 【问题描述】:

如果联系人中的 value 属性与 selectedContact 中的值匹配,我想创建一个包含联系人对象的新数组。有更简单的方法吗?

selectedContact: number[] = [0,2] //value
contacts: Contact[] = [ 
  firstName:"Dan";
  lastName:"Chong";
  email:"danc@mail.com";
  value:0;
,
 
  firstName:"Mark";
  lastName:"Wong";
  email:"markw@mail.com";
  value:1;
,
 
  firstName:"Layla";
  lastName:"Sng";
  email:"layla@mail.com";
  value: 2;
]

预期的最终结果:

newArray = [ 
 firstName:"Dan";
 lastName:"Chong";
 email:"danc@mail.com";
 value:0;
, 
 firstName:"Layla";
 lastName:"Sng";
 email:"layla@mail.com";
 value:2;
];

我目前的解决方案:

const newArray: Contact[] = [];
this.selectedContact.forEach(index => 
  newArray.push(this.contacts.find(c => c.value === index));
);

【问题讨论】:

未能提及当前解决方案与预期结果有何不同或遇到任何错误 肯定有更好的方法,但是你说的“更简单”是什么意思,你在找什么? 您对“更简单”的标准是什么?很难想出更简单的方法。不过可能有更有效的方法,例如创建 contacts 的索引以供重复使用。 对不起,我的意思是一种更有效的方法来执行此操作,而无需修改数组。当前的解决方案提供了所需的输出,但是否有更有效的方法,例如不使用 forEach 循环? 【参考方案1】:

就性能而言,迭代 selectedContacts 而不是 contacts 会更好,尤其是因为 contacts 已编入索引(作为数组)并且您正在通过索引进行选择。

假设contacts的长度是NselectedContacts的长度是M

由于selectedContactscontacts 的子集,我们知道M <= N。 对于大型联系人数据库,这种差异可能很大。

问题中的代码:

this.selectedContact.forEach(index => 
  newArray.push(this.contacts.find(c => c.value === index));
);

具有O(M*N),因为它迭代selectedContactO(M),并且在每次迭代中它都会在contacts (O(N)) 中找到一个值。

已接受答案中的代码遍历contact (O(N)) 并在selectedContact 中查找值O(M)。这使得算法等效,O(N*M)

在您的示例中,您已经有了一种按号码查找联系人的廉价方法,因为 contacts 是一个数组,而您的索引只是数组中的索引。

这意味着你可以使用这样的代码:

return this.selectedContact.map(index => this.contacts[index]);

由于按索引访问数组元素具有O(1),因此它将具有O(M),这是大小中最小的。

如果您不能使用数组索引作为键,您可以使用其他数据结构,例如Map,其中 id 是键,联系人是值。这将具有相似的查找速度(大致为O(1))。

【讨论】:

我明白了。谢谢你的详细解释!! :)【参考方案2】:

您可以使用Array.prototype.filter()

filter() 方法创建一个新数组,其中包含通过所提供函数实现的测试的所有元素。

和Array.prototype.includes()

includes() 方法判断数组是否包含某个元素,根据需要返回真或假。

工作代码示例:

var selectedContact = [0,2];
var contacts = [ 
  firstName: "Dan",
  lastName: "Chong",
  email: "danc@mail.com",
  value: 0
,
 
  firstName: "Mark",
  lastName: "Wong",
  email: "markw@mail.com",
  value: 1
,
 
  firstName: "Layla",
  lastName: "Sng",
  email: "layla@mail.com",
  value: 2
]
let newArray =  contacts.filter(c => selectedContact.includes(c.value));

console.log(newArray);

【讨论】:

@iBlehhz——是的,但“有效”并不是衡量效率的标准。 ;-) 这在 selectedContacts 很小的情况下会很有效,但如果不是,索引解决方案可能会更好(假设可以收回创建索引的成本)。

以上是关于如果属性与另一个数组匹配,则检索数组中的对象的主要内容,如果未能解决你的问题,请参考以下文章

js正则和数组

ECMAScript5RegExp对象

ElasticSearch中的关于对象数组查询,请注意要正确使用Nested类型

检索数组列表中的最后一个对象? Java [重复]

js之正则

js 如何正则匹配多个,像php 的preg_match()