Q:

how to loop through array of objects and check if a value in that object matches an item in another array using lodash

I have an array of items which are featured components like this:
var featuredIds = ['footerB', 'headerA', 'landingA'];

I also have an array of objects that looks something like this:
[{
    "title": "first footer",
    "section": "structure",
    "categoryId": "footer",
    "uId": "footerA"
  },{
    "title": "second footer",
    "section": "structure",
    "categoryId": "footer",
    "uId": "footerB"
  },
  {
    "title": "first header",
    "section": "structure",
    "categoryId": "header",
    "uId": "headerA"
  },
  {
    "title": "first header",
    "section": "structure",
    "categoryId": "header",
    "uId": "headerB"
  },
  {
    "title": "first landing",
    "section": "structure",
    "categoryId": "landing",
    "uId": "landingA"
  },
  {
    "title": "second landing",
    "section": "structure",
    "categoryId": "landing",
    "uId": "landingB"
  },
  {
    "title": "third landing",
    "section": "structure",
    "categoryId": "landing",
    "uId": "landingC"
  },
  {
    "title": "first nav",
    "section": "structure",
    "categoryId": "navigation",
    "uId": "navA"
  },{
    "title": "first footer",
    "section": "components",
    "categoryId": "blog",
      "uId": "blogA"
  },
  {
    "title": "second footer",
    "section": "components",
    "categoryId": "blog",
    "uId": "blogB"
  },
  {
    "title": "first header",
    "section": "components",
    "categoryId": "contact_button",
    "uId": "contact_buttonA"
  },
  {
    "title": "first landing",
    "section": "components",
    "categoryId": "content_bloc",
    "uId": "content_blocA"
  },
  {
    "title": "second landing",
    "section": "components",
    "categoryId": "content_bloc",
    "uId": "content_blocB"
  },
  {
    "title": "third landing",
    "section": "components",
    "categoryId": "content_bloc",
    "uId": "content_blocC"
  },
  {
    "title": "first nav",
    "section": "components",
    "categoryId": "cover",
    "uId": "coverA"
  }]

I want to create a new array which only holds the components that match the featureIds I provide in the array of featureIds which would look like this:
[{
    "title": "second footer",
    "section": "structure",
    "categoryId": "footer",
    "uId": "footerB"
  },{
    "title": "first header",
    "section": "structure",
    "categoryId": "header",
    "uId": "headerA"
  },
  {
    "title": "first landing",
    "section": "structure",
    "categoryId": "landing",
    "uId": "landingA"
  }]

I have looked at using _.some, _.find and a few others but haven't been able to get the result I am looking for. I have written this already using a double for loop which is why I want to us lodash to cut that out/learn something new.

A:

You can use lodash's chain with _.keyBy() and _.at():

function filterBy(arr, filters) {
  return _(features)
  .keyBy('uId')
  .at(filters)
  .value();
}

var features = [{
  "title": "first footer",
  "section": "structure",
  "categoryId": "footer",
  "uId": "footerA"
}, {
  "title": "second footer",
  "section": "structure",
  "categoryId": "footer",
  "uId": "footerB"
}, {
  "title": "first header",
  "section": "structure",
  "categoryId": "header",
  "uId": "headerA"
}, {
  "title": "first header",
  "section": "structure",
  "categoryId": "header",
  "uId": "headerB"
}, {
  "title": "first landing",
  "section": "structure",
  "categoryId": "landing",
  "uId": "landingA"
}, {
  "title": "second landing",
  "section": "structure",
  "categoryId": "landing",
  "uId": "landingB"
}, {
  "title": "third landing",
  "section": "structure",
  "categoryId": "landing",
  "uId": "landingC"
}, {
  "title": "first nav",
  "section": "structure",
  "categoryId": "navigation",
  "uId": "navA"
}, {
  "title": "first footer",
  "section": "components",
  "categoryId": "blog",
  "uId": "blogA"
}, {
  "title": "second footer",
  "section": "components",
  "categoryId": "blog",
  "uId": "blogB"
}, {
  "title": "first header",
  "section": "components",
  "categoryId": "contact_button",
  "uId": "contact_buttonA"
}, {
  "title": "first landing",
  "section": "components",
  "categoryId": "content_bloc",
  "uId": "content_blocA"
}, {
  "title": "second landing",
  "section": "components",
  "categoryId": "content_bloc",
  "uId": "content_blocB"
}, {
  "title": "third landing",
  "section": "components",
  "categoryId": "content_bloc",
  "uId": "content_blocC"
}, {
  "title": "first nav",
  "section": "components",
  "categoryId": "cover",
  "uId": "coverA"
}];

var featuredIds = ['footerB', 'headerA', 'landingA'];

var result = filterBy(features, featuredIds);

console.log(result);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.16.6/lodash.min.js"></script>

Or if you can use ES6, a combination of Array.prototype.filter() and Set:

const filterBy = (arr, filters) => {
  const filtersSet = new Set(filters);
  
  return arr.filter((item) => filtersSet.has(item.uId));
};

const featuredIds = ['footerB', 'headerA', 'landingA'];

const features = [{
  "title": "first footer",
  "section": "structure",
  "categoryId": "footer",
  "uId": "footerA"
}, {
  "title": "second footer",
  "section": "structure",
  "categoryId": "footer",
  "uId": "footerB"
}, {
  "title": "first header",
  "section": "structure",
  "categoryId": "header",
  "uId": "headerA"
}, {
  "title": "first header",
  "section": "structure",
  "categoryId": "header",
  "uId": "headerB"
}, {
  "title": "first landing",
  "section": "structure",
  "categoryId": "landing",
  "uId": "landingA"
}, {
  "title": "second landing",
  "section": "structure",
  "categoryId": "landing",
  "uId": "landingB"
}, {
  "title": "third landing",
  "section": "structure",
  "categoryId": "landing",
  "uId": "landingC"
}, {
  "title": "first nav",
  "section": "structure",
  "categoryId": "navigation",
  "uId": "navA"
}, {
  "title": "first footer",
  "section": "components",
  "categoryId": "blog",
  "uId": "blogA"
}, {
  "title": "second footer",
  "section": "components",
  "categoryId": "blog",
  "uId": "blogB"
}, {
  "title": "first header",
  "section": "components",
  "categoryId": "contact_button",
  "uId": "contact_buttonA"
}, {
  "title": "first landing",
  "section": "components",
  "categoryId": "content_bloc",
  "uId": "content_blocA"
}, {
  "title": "second landing",
  "section": "components",
  "categoryId": "content_bloc",
  "uId": "content_blocB"
}, {
  "title": "third landing",
  "section": "components",
  "categoryId": "content_bloc",
  "uId": "content_blocC"
}, {
  "title": "first nav",
  "section": "components",
  "categoryId": "cover",
  "uId": "coverA"
}];

const result = filterBy(features, featuredIds);

console.log(result);

Another lodash option is _.intersectionWith():

function filterBy(arr, filters) {
  return _.intersectionWith(arr, filters, function(value, filter) {
    return value.uId === filter;
  });
}

var features = [{
  "title": "first footer",
  "section": "structure",
  "categoryId": "footer",
  "uId": "footerA"
}, {
  "title": "second footer",
  "section": "structure",
  "categoryId": "footer",
  "uId": "footerB"
}, {
  "title": "first header",
  "section": "structure",
  "categoryId": "header",
  "uId": "headerA"
}, {
  "title": "first header",
  "section": "structure",
  "categoryId": "header",
  "uId": "headerB"
}, {
  "title": "first landing",
  "section": "structure",
  "categoryId": "landing",
  "uId": "landingA"
}, {
  "title": "second landing",
  "section": "structure",
  "categoryId": "landing",
  "uId": "landingB"
}, {
  "title": "third landing",
  "section": "structure",
  "categoryId": "landing",
  "uId": "landingC"
}, {
  "title": "first nav",
  "section": "structure",
  "categoryId": "navigation",
  "uId": "navA"
}, {
  "title": "first footer",
  "section": "components",
  "categoryId": "blog",
  "uId": "blogA"
}, {
  "title": "second footer",
  "section": "components",
  "categoryId": "blog",
  "uId": "blogB"
}, {
  "title": "first header",
  "section": "components",
  "categoryId": "contact_button",
  "uId": "contact_buttonA"
}, {
  "title": "first landing",
  "section": "components",
  "categoryId": "content_bloc",
  "uId": "content_blocA"
}, {
  "title": "second landing",
  "section": "components",
  "categoryId": "content_bloc",
  "uId": "content_blocB"
}, {
  "title": "third landing",
  "section": "components",
  "categoryId": "content_bloc",
  "uId": "content_blocC"
}, {
  "title": "first nav",
  "section": "components",
  "categoryId": "cover",
  "uId": "coverA"
}];

var featuredIds = ['footerB', 'headerA', 'landingA'];

var result = filterBy(features, featuredIds);

console.log(result);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.16.6/lodash.min.js"></script>

