lodash 过滤 属性 array of array
lodash filter by property array of array
我有一组拥有 属性 数组 'rights' 的用户,我想过滤掉拥有特定权限的用户。我想按数组过滤,所以如果我想要所有拥有完全权限的用户 ['full'] 或拥有完全和编辑权限的用户 ['full','edit']。我对使用 lodash 还很陌生,我想我可以将一些链接在一起,但我不确定是否有更有效的方法。
这是我的笨蛋:http://plnkr.co/edit/5PCvaDJaXF4uxRowVBlK?p=preview
结果['full']:
[{
"name": "Company1 Admin",
"rights": [
"full"
]
},
{
"name": "FullRights Company1",
"rights": [
"full","review"
]
}]
结果['full','edit']:
[{
"name": "Company1 Admin",
"rights": [
"full"
]
},
{
"name": "FullRights Company1",
"rights": [
"full","review"
]
},
{
"name": "EditRights Company1",
"rights": [
"edit"
]
}]
代码:
var users = [
{
"name": "Company1 Admin",
"rights": [
"full"
]
},
{
"name": "FullRights Company1",
"rights": [
"full","review"
]
},
{
"name": "ApproveRights Company1",
"rights": [
"approve","review"
]
},
{
"name": "EditRights Company1",
"rights": [
"edit"
]
},
{
"name": "ReviewRights Company1",
"rights": [
"review"
]
},
{
"name": "NoRights Company1",
"rights": [
"none"
]
}
];
var tUsers = [];
var filterRights = ['full','edit'];
_.forEach(users, function(user) {
if (_.intersection(user.rights, filterRights).length > 0) {
tUsers.push(user);
}
}) ;
//console.log('users', JSON.stringify(users, null, 2));
console.log('tUsers', JSON.stringify(tUsers, null, 2));
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/3.10.1/lodash.min.js"></script>
来自docs
_.filter(collection, predicate, thisArg);
Arguments
collection (Array|Object|string): The collection to iterate over.
[predicate=_.identity] (Function|Object|string): The function invoked per iteration.
[thisArg] (*): The this binding of predicate.
当您想连接不同的处理步骤时,链接非常有用。
如果您的问题陈述是
- 按权利过滤
- 按年龄最大的人排序
- 拿10个
那么链接就很有意义了。
这个问题似乎主要是关于过滤的自定义逻辑。
var users = [/* Your user data here */];
function filterByRights (users, rights) {
return _.filter(users, function (user) {
return _.any(user.rights, function (right) {
return _.contains(rights, right);
});
});
}
filterByRights(users, ['full', 'edit']); // [/*Users with full or edit rights*/]
我认为我的示例很好,因为它不依赖于条件逻辑。它使用 lodash 定义的方法,如 any
和 contains
性能问题
我想详细说明您对性能的担忧。这里有几点。
您的问题代码正在维护自己的用户过滤机制。虽然这是一个非常好的解决方案,但您应该选择让维护 lodash 的人处理这个逻辑。他们可能花了很多时间优化如何从原始数组创建另一个数组。
_.any
比 _.intersection
更有效率。 _.intersection
需要处理每个元素才能知道交集是什么。 _.any
在遇到第一个通过谓词的元素时停止,否则它会检查每个元素。这一点是次要的,因为有少量的“权利”
我给出的示例可能更“lodash 标准”。您通常可以完全使用 lodash 定义的方法和 trivial 谓词进行数据转换。
我认为您 intersection() (I've never seen any performance issues with this function). Here's how I would compose an iteratee using flow() 的选择是正确的:
_.filter(users, _.flow(
_.property('rights'),
_.partial(_.intersection, filterRights),
_.size
));
property() function gets the rights
property, and passes it to intersection()
. We've already partially-applied the filterRights
array. Lastly, the size() function is necessary to pass a thruthy/falesy value to filter().
这是对@t3dodson 回答的更新。如果使用当前 (4.17.4) Lodash 版本,您现在应该使用以下代码片段:
function filterByRights (users, rights) {
return _.filter(users, function (user) {
return _.some(user.rights, function (right) {
return _.includes(rights, right);
});
});
}
来自Changelog:
Removed _.contains in favor of _.includes
Removed _.any in favor of _.some
我有一组拥有 属性 数组 'rights' 的用户,我想过滤掉拥有特定权限的用户。我想按数组过滤,所以如果我想要所有拥有完全权限的用户 ['full'] 或拥有完全和编辑权限的用户 ['full','edit']。我对使用 lodash 还很陌生,我想我可以将一些链接在一起,但我不确定是否有更有效的方法。
这是我的笨蛋:http://plnkr.co/edit/5PCvaDJaXF4uxRowVBlK?p=preview
结果['full']:
[{
"name": "Company1 Admin",
"rights": [
"full"
]
},
{
"name": "FullRights Company1",
"rights": [
"full","review"
]
}]
结果['full','edit']:
[{
"name": "Company1 Admin",
"rights": [
"full"
]
},
{
"name": "FullRights Company1",
"rights": [
"full","review"
]
},
{
"name": "EditRights Company1",
"rights": [
"edit"
]
}]
代码:
var users = [
{
"name": "Company1 Admin",
"rights": [
"full"
]
},
{
"name": "FullRights Company1",
"rights": [
"full","review"
]
},
{
"name": "ApproveRights Company1",
"rights": [
"approve","review"
]
},
{
"name": "EditRights Company1",
"rights": [
"edit"
]
},
{
"name": "ReviewRights Company1",
"rights": [
"review"
]
},
{
"name": "NoRights Company1",
"rights": [
"none"
]
}
];
var tUsers = [];
var filterRights = ['full','edit'];
_.forEach(users, function(user) {
if (_.intersection(user.rights, filterRights).length > 0) {
tUsers.push(user);
}
}) ;
//console.log('users', JSON.stringify(users, null, 2));
console.log('tUsers', JSON.stringify(tUsers, null, 2));
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/3.10.1/lodash.min.js"></script>
来自docs
_.filter(collection, predicate, thisArg);
Arguments
collection (Array|Object|string): The collection to iterate over.
[predicate=_.identity] (Function|Object|string): The function invoked per iteration.
[thisArg] (*): The this binding of predicate.
当您想连接不同的处理步骤时,链接非常有用。
如果您的问题陈述是
- 按权利过滤
- 按年龄最大的人排序
- 拿10个
那么链接就很有意义了。
这个问题似乎主要是关于过滤的自定义逻辑。
var users = [/* Your user data here */];
function filterByRights (users, rights) {
return _.filter(users, function (user) {
return _.any(user.rights, function (right) {
return _.contains(rights, right);
});
});
}
filterByRights(users, ['full', 'edit']); // [/*Users with full or edit rights*/]
我认为我的示例很好,因为它不依赖于条件逻辑。它使用 lodash 定义的方法,如 any
和 contains
性能问题
我想详细说明您对性能的担忧。这里有几点。
您的问题代码正在维护自己的用户过滤机制。虽然这是一个非常好的解决方案,但您应该选择让维护 lodash 的人处理这个逻辑。他们可能花了很多时间优化如何从原始数组创建另一个数组。
_.any
比_.intersection
更有效率。_.intersection
需要处理每个元素才能知道交集是什么。_.any
在遇到第一个通过谓词的元素时停止,否则它会检查每个元素。这一点是次要的,因为有少量的“权利”我给出的示例可能更“lodash 标准”。您通常可以完全使用 lodash 定义的方法和 trivial 谓词进行数据转换。
我认为您 intersection() (I've never seen any performance issues with this function). Here's how I would compose an iteratee using flow() 的选择是正确的:
_.filter(users, _.flow(
_.property('rights'),
_.partial(_.intersection, filterRights),
_.size
));
property() function gets the rights
property, and passes it to intersection()
. We've already partially-applied the filterRights
array. Lastly, the size() function is necessary to pass a thruthy/falesy value to filter().
这是对@t3dodson 回答的更新。如果使用当前 (4.17.4) Lodash 版本,您现在应该使用以下代码片段:
function filterByRights (users, rights) {
return _.filter(users, function (user) {
return _.some(user.rights, function (right) {
return _.includes(rights, right);
});
});
}
来自Changelog:
Removed _.contains in favor of _.includes
Removed _.any in favor of _.some