0

I am trying to avoid importing lodash for a simple filter. I am trying to do something similar to this...

// Items
[
  { "title": "a", "name": "a", "location": "here"},
  { "title": "b", "name": "a", "location": "here"}, 
  { "title": "d", "location": "there"}, 
]
// Filter
{ "name" : "a", "location": "here" }

Should return the first two items. In lodash this is done by something similar to _.filter(Items, Filter). I would like to implement this without lodash or a bunch of code and getting Object.keys. Is there a simple way in modern Javascript to handle this?

2
  • I tried searching but if this was already asked in a diff way let me know and I will delete. Commented Feb 11, 2022 at 17:33
  • github.com/lodash/lodash/blob/master/filter.js Commented Feb 11, 2022 at 17:38

3 Answers 3

1

Here's what I came up with, seems to work well

let foo = [
  { "title": "a", "name": "a", "location": "here"},
  { "title": "b", "name": "a", "location": "here"}, 
  { "title": "d", "location": "there"}, 
];

let bar = { "name" : "a", "location": "here" };

let result = foo.filter(obj =>
  Object.entries(bar).every(([k,v]) => obj[k]===v)
);

console.log(result);

Sign up to request clarification or add additional context in comments.

1 Comment

You beat me to it by a couple of minutes. Good answer. Though I'd add a little more whitespace.
0

I don't believe there's a "simple way in modern Javascript to handle this" but if you don't have a hard requirement on avoiding Object.keys you could write a helper function to do this:

const myItems = [
  { "title": "a", "name": "a", "location": "here"},
  { "title": "b", "name": "a", "location": "here"}, 
  { "title": "d", "location": "there"}, 
]

const myFilter = { "name" : "a", "location": "here" };

const filter = (items, filterBy) => 
  items.filter(item => 
    Object.keys(filterBy).every(key => item[key] === filterBy[key])
  )

alert(JSON.stringify(filter(myItems, myFilter)));

1 Comment

we wrote basically identical solutions lol, didn't see yours until I refreshed the page
0

You could get the entries of the filter in advance to prevent getting th entries for every filtering iteration.

const
    filter = (array, filter) => {
        const
            filterBy = entries => o => entries.every(([k, v]) => o[k] === v);

        return items.filter(filterBy(Object.entries(filters)));
    },
    items = [{ title: "a", name: "a", location: "here" }, { title: "b", name: "a", location: "here" }, { title: "d", location: "there"}],
    filters = { name: "a", location: "here" },
    result = filter(items, filters);

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.