プロパティ値の配列を使用してコレクションをフィルタリングしたいと思います。 IDの配列を指定すると、一致するIDを持つオブジェクトを返します。 lodash
/underscore
を使用するショートカットメソッドはありますか?
var collections = [{ id: 1, name: 'xyz' },
{ id: 2, name: 'ds' },
{ id: 3, name: 'rtrt' },
{ id: 4, name: 'nhf' },
{ id: 5, name: 'qwe' }];
var ids = [1,3,4];
// This works, but any better way?
var filtered = _.select(collections, function(c){
return ids.indexOf(c.id) != -1
});
この種のパターンを頻繁に使用する場合、次のようなミックスインを作成できますが、元のコードとは根本的に異なることは何もしていません。開発者にとって使いやすくなります。
_.mixin({
'findByValues': function(collection, property, values) {
return _.filter(collection, function(item) {
return _.contains(values, item[property]);
});
}
});
その後、このように使用できます。
var collections = [
{id: 1, name: 'xyz'},
{id: 2, name: 'ds'},
{id: 3, name: 'rtrt'},
{id: 4, name: 'nhf'},
{id: 5, name: 'qwe'}
];
var filtered = _.findByValues(collections, "id", [1,3,4]);
Update-上記の答えは古くて不格好です。より洗練されたソリューションを得るには、 Adam Boduchからの回答 を使用してください。
_(collections)
.keyBy('id') // or .indexBy() if using lodash 3.x
.at(ids)
.value();
このようにフィルタリングすることもできます
var collections = [{ id: 1, name: 'xyz' },
{ id: 2, name: 'ds' },
{ id: 3, name: 'rtrt' },
{ id: 4, name: 'nhf' },
{ id: 5, name: 'qwe' }];
var filtered_ids = _.filter(collections, function(p){
return _.includes([1,3,4], p.id);
});
console.log(filtered_ids);
jessegavin's answerが好きですが、 lodash-deep を使用して詳細なプロパティマッチングを展開しました。
var posts = [{ term: { name: 'A', process: '123A' } },
{ term: { name: 'B', process: '123B' } },
{ term: { name: 'C', process: '123C' } }];
var result = _.filterByValues(posts, 'term.process', ['123A', '123C']);
// results in objects A and C to be returned
_.mixin({
'filterByValues': function(collection, key, values) {
return _.filter(collection, function(o) {
return _.contains(values, resolveKey(o, key));
});
}
});
function resolveKey(obj, key) {
return (typeof key == 'function') ? key(obj) : _.deepGet(obj, key);
}
Lodash-deepを信頼しない場合、または名前にドットが含まれるプロパティのサポートが必要な場合は、より防御的で堅牢なバージョンがあります。
function resolveKey(obj, key) {
if (obj == null || key == null) {
return undefined;
}
var resolved = undefined;
if (typeof key == 'function') {
resolved = key(obj);
} else if (typeof key == 'string' ) {
resolved = obj[key];
if (resolved == null && key.indexOf(".") != -1) {
resolved = _.deepGet(obj, key);
}
}
return resolved;
}
一意ではない値でフィルター処理したかったため、これらの回答は私にとってはうまくいきませんでした。 keyBy
をgroupBy
に変更すると、手に入れることができます。
_(collections)
.groupBy(attribute)
.pick(possibleValues)
.values()
.flatten()
.value();
私の最初の用途は物を落とすことだったので、pick
をomit
に切り替えました。
出発点をありがとう Adam Boduch 。
これらの回答の多くは時代遅れであるか、またはLodashのドキュメントにリストされていない補助機能が含まれていることに気付きました。受け入れられた回答には、廃止された関数_.contains
および更新する必要があります。
ES6の答えはここにあります。
Lodash v4.17.4 に基づく
_.mixin( {
filterByValues: ( c, k, v ) => _.filter(
c, o => _.indexOf( v, o[ k ] ) !== -1
)
} );
そしてそのように呼び出されます:
_.filterByValues(
[
{
name: 'StackOverflow'
},
{
name: 'ServerFault'
},
{
name: 'AskDifferent'
}
],
'name',
[ 'StackOverflow', 'ServerFault' ]
);
// => [ { name: 'StackOverflow' }, { name: 'ServerFault' } ]
これは私にとってはうまくいきました:
let output = _.filter(collections, (v) => _.includes(ids, v.id));