Skip to content

Instantly share code, notes, and snippets.

@victorouse
Created March 4, 2018 01:08
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save victorouse/eda118b8d39b7618147e5414c8c81155 to your computer and use it in GitHub Desktop.
Save victorouse/eda118b8d39b7618147e5414c8c81155 to your computer and use it in GitHub Desktop.
Facebook Interview: Filter Properties
function createExcludedMap(excludes) {
return excludes.reduce((map, pair) => {
const values = map.get(pair.k);
if (values) {
values.push(pair.v);
return map.set(pair.k, values);
}
return map.set(pair.k, [pair.v]);
}, new Map());
}
/*
function excludeItems(items, excludes) {
excludes.forEach((pair, outer) => {
items = items.filter((item, inner) => {
return item[pair.k] !== pair.v;
});
});
return items;
}
*/
/*
function excludeItems(items, excludes) {
const included = [];
for (const item of items) {
let excluded = false;
for (const [key, values] of excludesMap) {
if (item[key] && values.includes(item[key])) {
excluded = true;
break;
}
}
if (!excluded) {
included.push(item);
}
}
return included;
}
*/
function excludeItems(items, excludes) {
for (const item of items) {
for (const [key, values] of excludesMap) {
items = items.filter((item) => !values.includes(item[key]));
}
}
return items;
}
const items = [
{ color: 'red', type: 'tv', age: 18 },
{ color: 'red', type: 'phone', age: 20 },
{ color: 'silver', type: 'tv', age: 18 },
{ color: 'silver', type: 'phone', age: 20 }
];
const excludes = [
{ k: 'color', v: 'red' },
{ k: 'color', v: 'blue' },
{ k: 'type', v: 'phone' },
];
/*
const excludesMap = new Map(
['color', ['red', 'blue']],
['type', ['phone']]
);
*/
const excludesMap = createExcludedMap(excludes);
console.log('result', excludeItems(items, excludesMap));
@vmvargas
Copy link

vmvargas commented May 3, 2021

Rather than chaining items on an array for excludesMap, you could use an obj with O(1) access

excludesMap {
  'color' => { red: true, blue: true },
  'type' => { phone: true }
}

This is how I did it:

function createExcludedMap(excludes) {
  return excludes.reduce((map, pair) => {
    if (map.has(pair.k)) {
      const prevVal = map.get(pair.k);
      return map.set(pair.k, {
        ...prevVal,
        [pair.v]: true,
      });
    } else return map.set(pair.k, { [pair.v]: true });
  }, new Map());
}

function excludeItems(items, excludes) {
  return items.filter((item) => {
    for (prop in item) {
      if (excludes.has(prop) && excludes.get(prop)[item[prop]]) return false;
    }
    return true;
  });
}

Breaking down:

excludes.get(prop)[item[prop]]

In the 1st iteration, you get:

prop // 'color'
excludes.get(prop) //  { blue: true, red: true}
item[prop] // current item's property value, i.e., 'red'

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment