目的
创建一个查看列表(集合)的函数,并返回具有等效属性值(源)的所有对象的数组。
示例#1
function where(collection, source) {
var arr = [];
return arr;
}
where([
{ first: 'Romeo', last: 'Montague' },
{ first: 'Mercutio', last: null },
{ first: 'Tybalt', last: 'Capulet' }],
{ last: 'Capulet' });
预期输出#1
[{ first: 'Tybalt', last: 'Capulet' }]
示例#2
where(
[{ 'a': 1 },
{ 'a': 1 },
{ 'a': 1, 'b': 2 }],
{ 'a': 1 }),
预期输出#2
[{ 'a': 1 }, { 'a': 1 }, { 'a': 1, 'b': 2 }]
问题
答案 0 :(得分:1)
由于您无法使用外部库,因此这是一种简单的方法来满足您的需求:
function where(collection, source) {
var keys = Object.keys(source);
return collection.filter(function (item) {
return keys.every(function (key) {
return source[key] == item[key];
});
});
}
答案 1 :(得分:0)
<强> - &GT;解决方案1:使用Lodash Where
对于此类问题,您可以使用Lodash实用程序库。
Lodash已经拥有你需要的where功能。
见下面的例子。
var out = _.where([{
first: 'Romeo',
last: 'Montague'
}, {
first: 'Mercutio',
last: null
}, {
first: 'Tybalt',
last: 'Capulet'
}],
{
last: 'Capulet'
});
document.getElementById('out').innerHTML = JSON.stringify(out);
var out2 = _.where(
[{
'a': 1
}, {
'a': 1
}, {
'a': 1,
'b': 2
}],
{
'a': 1
});
document.getElementById('out2').innerHTML = JSON.stringify(out2);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/3.8.0/lodash.js"></script>
<div id="out"></div>
<hr/>
<div id="out2"></div>
<强> - &GT;解决方案2:自定义Where
实施
此实现适用于字符串,单个对象,一个级别对象和多个级别对象。
function typeOf(o) {
return Object.prototype.toString.call(o).split(' ')[1].split(']')[0].toLowerCase();
}
function isUndefined(o) {
return typeOf(o) === 'undefined';
}
function where(collection, source) {
var checkArr = [];
if (typeOf(collection) === 'object') {
checkArr = [collection];
} else if (typeOf(collection) === 'array') {
checkArr = collection;
}
function isObjectSemiSame(obj, source, u) {
return Object.keys(source).every(function(key) {
if (isUndefined(obj) || isUndefined(obj[key])) {
return;
}
if (typeOf(source[key]) === 'object' || typeOf(source[key]) === 'array') {
return isObjectSemiSame(obj[key], source[key]);
}
return source[key] === obj[key];
});
}
return checkArr.filter(function(item) {
return isObjectSemiSame(item, source);
});
}
Jasmine使用字符串,单个对象,一个级别对象和多个级别对象测试where
。
function typeOf(o) {
return Object.prototype.toString.call(o).split(' ')[1].split(']')[0].toLowerCase();
}
function isUndefined(o) {
return typeOf(o) === 'undefined';
}
function where(collection, source) {
var checkArr = [];
if (typeOf(collection) === 'object') {
checkArr = [collection];
} else if (typeOf(collection) === 'array') {
checkArr = collection;
}
function isObjectSemiSame(obj, source, u) {
return Object.keys(source).every(function(key) {
if (isUndefined(obj) || isUndefined(obj[key])) {
return;
}
if (typeOf(source[key]) === 'object' || typeOf(source[key]) === 'array') {
return isObjectSemiSame(obj[key], source[key]);
}
return source[key] === obj[key];
});
}
return checkArr.filter(function(item) {
return isObjectSemiSame(item, source);
});
}
describe('where method', function() {
it('testing with strings', function() {
var collection = [
"one",
"two",
"three"
];
var collection = [
"bamboo",
"two",
"bamboo",
"link"
];
expect(where(collection, "two")).toEqual(["two"]);
expect(where(collection, "bamboo")).toEqual(["bamboo", "bamboo"]);
});
it('testing with one object', function() {
var collection1 = {
name: 'raju',
age: 23,
};
var collection2 = {
name: 'Friko',
age: 36,
};
expect(where(collection1, {
name: 'raju'
})).toEqual([collection1]);
expect(where(collection1, {
name: 'Dump'
})).toEqual([]);
expect(where(collection2, {
age: 36
})).toEqual([collection2]);
expect(where(collection2, {
car: 'audi'
})).toEqual([]);
});
it('testing with one level object', function() {
var collection = [{
name: 'jack',
age: 25
}, {
name: 'missi',
age: 23
}, {
name: 'reddy',
age: 46
}];
var source1 = {
name: 'reddy'
};
var source2 = {
age: 25
};
expect(where(collection, source1)).toEqual([collection[2]]);
expect(where(collection, source2)).toEqual([collection[0]]);
});
it('testing with multilevel object', function() {
var collection = [{
name: 'jack',
age: 25,
level1: {
name: 'l1',
level2: {
name: 'l2',
level3: {
name: 'l3'
}
}
}
}, {
name: 'missi',
age: 23,
level1: {
name: 'l1'
}
}, {
name: 'reddy',
age: 46,
feature: {
flag: false
}
}];
var source1 = {
level1: {
name: 'l1'
}
};
var source2 = {
level1: {
name: 'l1',
level2: {
name: 'l2'
}
}
};
var source3 = {
feature: {
flag: false
}
};
expect(where(collection, source1).length).toBe(2);
expect(where(collection, source1)).toEqual(jasmine.arrayContaining([
collection[0],
collection[1]
]));
expect(where(collection, source2)).toEqual([collection[0]]);
expect(where(collection, source3)).toEqual([collection[2]]);
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jasmine/2.2.1/jasmine.min.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/jasmine/2.2.1/jasmine.min.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/jasmine/2.2.1/jasmine-html.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jasmine/2.2.1/boot.min.js"></script>
更新:通过茉莉花测试添加了自定义where
实施