Where art thou
写一个 function,它遍历一个对象数组(第一个参数)并返回一个包含相匹配的属性-值对(第二个参数)的所有对象的数组。如果返回的数组中包含 source 对象的属性-值对,那么此对象的每一个属性-值对都必须存在于 collection 的对象中。
例如,如果第一个参数是 [{ first: "Romeo", last: "Montague" }, { first: "Mercutio", last: null }, { first: "Tybalt", last: "Capulet" }]
,第二个参数是 { last: "Capulet" }
,那么你必须从数组(第一个参数)返回其中的第三个对象,因为它包含了作为第二个参数传递的属性-值对。
思路:
(1)将source的属性名转化为数组;
(2)找出没有这些属性名的对象,从collection数组中剔除出去;
(3)找出与给出属性名的属性值不符的对象,从collection数组中剔除出去;
知识点:
(1)Object.keys()方法会返回一个由一个给定对象的自身可枚举属性组成的数组;
var proArr = Object.keys(source);
(2)Object.hasOwnProperty()方法会返回一个布尔值,指示对象是否具有指定的属性作为自身(不继承)属性;
1 for (var i = 0; i < collection.length; i++) { 2 for (var j = 0; j < proArr.length; j++) { 3 //找出没有这种属性的对象(属性可能有两种以上,只要一个没有就可以排除,所以反向选择是最方便的) 4 if (collection[i].hasOwnProperty(proArr[j]) === false) { 5 array.push(collection[i]); 6 } 7 } 8 }
(3)Object.getOwnPropertyDescriptor() 方法返回指定对象上一个自有属性对应的属性描述符。(自有属性指的是直接赋予该对象的属性,不需要从原型链上进行查找的属性)
注意这里返回的是属性描述符,所以要获取到值要用.value();
1 for (var k = 0; k <collection.length; k++) { 2 for (var t = 0; t < proArr.length; t++) { 3 //找出与给出对象属性值不符合的对象,和上面一样,反向选择 4 if (Object.getOwnPropertyDescriptor(collection[k], proArr[t]).value !== Object.getOwnPropertyDescriptor(source, proArr[t]).value) { 5 finArr.push(collection[k]); 6 } 7 } 8 }
(4)Array.filter()方法创建一个新数组, 其包含通过所提供函数实现的测试的所有元素,就是过滤元素;
(5)Array.push()方法将一个或多个元素添加到数组的末尾,并返回数组的新长度。
代码:
1 function where(collection, source) { 2 var arr = []; 3 var array = []; 4 var finArr = []; 5 var proArr = Object.keys(source); 6 for (var i = 0; i < collection.length; i++) { 7 for (var j = 0; j < proArr.length; j++) { 8 //找出没有这种属性的对象(属性可能有两种以上,只要一个没有就可以排除,所以反向选择是最方便的) 9 if (collection[i].hasOwnProperty(proArr[j]) === false) { 10 array.push(collection[i]); 11 } 12 } 13 } 14 collection = collection.filter(function (value) { 15 //通过filter函数在collection数组中将没有这种属性的对象排除 16 if (array.indexOf(value) === -1) { 17 return value; 18 } 19 }); 20 21 for (var k = 0; k < collection.length; k++) { 22 for (var t = 0; t < proArr.length; t++) { 23 //找出与给出对象属性值不符合的对象,和上面一样,反向选择 24 if (Object.getOwnPropertyDescriptor(collection[k], proArr[t]).value !== Object.getOwnPropertyDescriptor(source, proArr[t]).value) { 25 finArr.push(collection[k]); 26 } 27 } 28 } 29 arr = collection.filter(function (value) { 30 //通过filter函数在collection数组中将没有这种属性值的对象排除 31 if (finArr.indexOf(value) === -1) { 32 return value; 33 } 34 }); 35 return arr; 36 }