[英]How to remove object in array if not present in another array
I want to remove an object in array if not present in another array. 我想删除另一个数组中不存在的对象。 I tried to search and found similar question in this link but have a different array source.
我试图搜索并在此链接中找到了类似的问题,但具有不同的数组源。
Here is the example from link above : 这是上面链接的示例:
var check = [1, 2, 3]; var allowed = [1]; var filtered = check.filter(function(item) { return allowed.indexOf(item) > -1; }); console.log(filtered);
Example above remove number in array check
if not present in array allowed
. 上面的示例删除数组中的数字,
check
是否在allowed
数组中不存在。 In my case the source array contain an object like example below : 就我而言,源数组包含一个类似于下面的示例的对象:
var check = [ { name: 'Peter', location: 'florida' }, { name: 'Robert', location: 'California' } ]; var allowed = [ { name: 'Robert', location: 'Boston' } ]; var filtered = check.filter(function(item) { return allowed.indexOf(item.name) > -1; }); console.log(filtered);
I tried to run the code and the result is an empty array. 我试图运行代码,结果是一个空数组。
Result i expect : 我期望的结果:
[
{
name: 'Robert',
location: 'California'
}
]
Anyone can please help me to make the result as i expect? 任何人都可以帮助我取得预期的结果吗?
You can use Array#find()
您可以使用
Array#find()
var check = [{ name: 'Peter', location: 'florida' }, { name: 'Robert', location: 'California' } ]; var allowed = [{ name: 'Robert', location: 'Boston' }]; var res = check.filter(function(cItem) { return allowed.find(function(aItem) { return cItem.name === aItem.name }) }) console.log(res)
You can map allowed
to just contain the criteria that you are looking for (name): 您可以将地图
allowed
只包含您要查找的条件(名称):
var allowed = [{
name: 'Robert',
location: 'Boston'
}]
.map(obj => obj.name);
That will create an array of just names which is easier to test the indexOf
这将创建一个仅包含名称的数组,从而更易于测试
indexOf
Example: 例:
var check = [{ name: 'Peter', location: 'florida' }, { name: 'Robert', location: 'California' } ]; var allowed = [{ name: 'Robert', location: 'Boston' }] .map(obj => obj.name); var filtered = check.filter(function(item) { return allowed.indexOf(item.name) > -1; }); console.log(filtered);
You need to check against the item names in the allowed
array. 您需要检查
allowed
数组中的项目名称。 Right now you're checking against the items in the allowed array, which type is an object. 现在,您正在检查允许的数组中的项目,该类型是一个对象。
Here's the problem: return allowed.indexOf(item.name) > -1;
这是问题所在:
return allowed.indexOf(item.name) > -1;
Maybe this approach helps: 也许这种方法可以帮助:
var check = [ { name: 'Peter', location: 'florida' }, { name: 'Robert', location: 'California' } ]; var allowed = [ { name: 'Robert', location: 'Boston' } ]; function containsName(name, array){ return array.find(item => item.name === name); } var filtered = check.filter(function(item) { return containsName(item.name, allowed) }); console.log(filtered);
The following intersect function would intersect any key on any given array of objects: 以下相交函数将与任何给定对象数组上的任何键相交:
var check = [ { name:'Peter', location:'florida' }, { name:'Robert', location:'California'} ]; var allowed = [ { name:'Robert', location:'Boston' } ]; function intersect(check, allowed) { var allowed_map = allowed.reduce(function(map, obj) { Object.keys(obj).forEach(function(key) { if (!map[key]) { map[key] = []; } map[key].push(obj[key]); }); return map; }, {}); return check.filter(function(item) { return Object.keys(item).find(function(key) { return allowed_map[key].indexOf(item[key]) != -1; }) }); } var filtered = intersect(check, allowed); var allowed2 = [{ name:'Bob', location:'California' }]; var filtered2 = intersect(check, allowed2); console.log('filtered',filtered); console.log('filtered2',filtered2);
There are multiple approaches depending on what you need. 有多种方法取决于您的需求。
For a dirty check where the objects will have the same memory reference on both arrays you can do the following. 要进行脏检查,对象在两个阵列上的引用都相同,可以执行以下操作。
var firstPerson = { name: 'Peter', location: 'florida' } var secondPerson = { name: 'Robert', location: 'California' } var allowed = [secondPerson]; var check = [firstPerson, secondPerson]; var result = check.filter(item => allowed.includes(item)); console.log(result);
For an specific attribute check you can use find
and compare the check
and allowed
, by an attribute like name
or location
对于特定的属性检查,您可以通过
name
或location
类的属性使用find
并比较check
和allowed
var check = [ { name: 'Peter', location: 'florida' }, { name: 'Robert', location: 'California' } ]; var allowed = [ { name: 'Robert', location: 'Boston' } ]; var result = check.filter(checkPerson => allowed.find(allowPerson => allowPerson.name === checkPerson.name)); console.log(result);
For a nested object check you would require to check the items recursively, I use this utility I created some time ago called deepCompare
, is an alternative to Lodash's isEqual
that only weights 880B 对于嵌套对象检查,您将需要递归检查项目,我使用了一段时间前创建的名为
deepCompare
实用程序,它是Lodash的isEqual
的替代方法,后者仅重880B
var check = [ { name: 'Peter', location: { street: "fridtjof nansens vei 8511", city: "ågotnes", state: "buskerud", postcode: "8766", coordinates: { latitude: "50.4828", longitude: "-84.6920" } } }, { name: 'Robert', location: { street: "schillerstraße 69", city: "velburg", state: "saarland", postcode: 72100, coordinates: { latitude: "30.4655", longitude: "9.1938" } } } ]; var allowed = [ { name: 'Robert', location: { street: "schillerstraße 69", city: "velburg", state: "saarland", postcode: 72100, coordinates: { latitude: "30.4655", longitude: "9.1938" } } } ]; var result = check.filter(checkPerson => allowed.some(allowPerson => deepCompare(checkPerson, allowPerson))); console.log(result);
<script> /** * Deep Compare * @param { * } value first entry value * @param { * } other second entry value * @param { Boolean } sorted Sort any array before deep comparison */ const deepCompare = (value, other, sorted) => { /** * Compare possible primitives * Object.is works like `===` but additionally differes positive from negative values * IE: * Object.is(-0, 0) // False * -0 === 0 // True */ if (Object.is(value, other)) return true; /** * Check if either value is undefined or the constructor is different for each value * given the case return false */ if (!value || !other || value.constructor !== other.constructor) return false; /** * Check Object and Array deep comparisons */ switch (value.constructor) { case Array: /** * Check if both values have the same amount of items * if they don't immediatelly omit the comparison and return false */ if (value.length === other.length) { return deepArrayCompare(value, other, sorted); } return false; case Object: /** * Check if both values have the same amount of keys * if they don't immediatelly omit the comparison and return false */ if (Object.keys(value).length === Object.keys(other).length) { return deepObjectCompare(value, other, sorted); } return false; } return false; }; /** * Deep Object Compare * @param { * } value first entry value * @param { * } other second entry value * * 'deepArrayCompare(Object.keys(value), Object.keys(other), sorted)' * This checks that both objects have the same keys * IE: * deepArrayCompare(Object.keys({ a: 1, b: 2, c:3 }), Object.keys({ a: 10, b: 22, c: 54 }), true) // True * deepArrayCompare(Object.keys({ a: 1, b: 2, c:3 }), Object.keys({ g: 1, f: 2, d: 3 }), true) // False * * 'Object.keys(value).every(key => deepCompare(value[key], other[key]))' * This iterates on each key of the object over a 'every' comparison and performs a deepCompare on both values * */ const deepObjectCompare = (value, other) => deepArrayCompare(Object.keys(value), Object.keys(other), true) && Object.keys(value).every(key => deepCompare(value[key], other[key])); /** * Deep Array Compare * @param { * } value first entry value * @param { * } other second entry value * @param { Boolean } sorted Sort any array before deep comparison * * '(sorted && value.sort(), sorted && other.sort(), ...)' * This manages the optional sorting through Comma Operator * * 'value.every((item, index) => deepCompare(item, other[index]))' * This performs the deepComparison of values between both arrays */ const deepArrayCompare = (value, other, sorted) => (sorted && value.sort(), sorted && other.sort(), value.every((item, index) => deepCompare(item, other[index]))); </script>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.