Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Javascript search for an object key in a set

Is it possible to use the javascript "Set" object to find an element with a certain key? Something like that:

let myObjects = [{"name":"a", "value":0}, {"name":"b", "value":1},{"name":"c", "value":2}];
let mySet = new Set(myObjects);
console.log(mySet.has({"name":"a"}));
like image 241
Alexandre Senges Avatar asked Jul 29 '17 12:07

Alexandre Senges


2 Answers

Not in that way, that would look for the specific object you're passing in, which isn't in the set.

If your starting point is an array of objects, you don't need a Set at all, just Array.prototype.find:

let myObjects = [{"name":"a", "value":0}, {"name":"b", "value":1},{"name":"c", "value":2}];
let found = myObjects.find(e => e.name === "a");
console.log(found);

If you already have a Set and want to search it for a match, you can use its iterator, either directly via for-of:

let myObjects = [{"name":"a", "value":0}, {"name":"b", "value":1},{"name":"c", "value":2}];
let mySet = new Set(myObjects);
let found = undefined; // the `= undefined` is just for emphasis; that's the default value it would have without an initializer
for (const e of mySet) {
  if (e.name === "a") {
    found = e;
    break;
  }
}
console.log(found);

...or indirectly via Array.from to (re)create (the)an array, and then use find:

let myObjects = [{"name":"a", "value":0}, {"name":"b", "value":1},{"name":"c", "value":2}];
let mySet = new Set(myObjects);
let found = Array.from(mySet).find(e => e.name === "a");
console.log(found);

If it's something you need to do often, you might give yourself a utility function for it:

const setFind = (set, cb) => {
  for (const e of set) {
    if (cb(e)) {
      return e;
    }
  }
  return undefined; // undefined` just for emphasis, `return;`
                    // would do effectively th same thing, as
                    // indeed would just not having a `return`
                    // at at all
}

let myObjects = [{"name":"a", "value":0}, {"name":"b", "value":1},{"name":"c", "value":2}];
let mySet = new Set(myObjects);
let found = setFind(mySet, e => e.name === "a");
console.log(found);

You could even put that on Set.prototype (making sure it's non-enumerable), but beware of conflicting with future additions to Set (for instance, I wouldn't be at all surprised if Set.prototype got a find method at some point).

like image 58
T.J. Crowder Avatar answered Oct 05 '22 15:10

T.J. Crowder


You may just want a Set of names:

 let myObjects = [{"name":"a", "value":0}, {"name":"b", "value":1},{"name":"c", "value":2}];

let map = new Set(myObjects.map(el=>el.name));
console.log(map.has("a"));

If you want to get an object by name,thats what a Map is for:

let myObjects = [{"name":"a", "value":0}, {"name":"b", "value":1},{"name":"c", "value":2}];

let map = new Map(myObjects.map(el=>[el.name,el]));
console.log(map.get("a"));
like image 40
Jonas Wilms Avatar answered Oct 05 '22 14:10

Jonas Wilms