Javascript 在集合中搜索对象键

2022-01-17 00:00:00 set key search javascript

是否可以使用 javascript "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"}));

推荐答案

不是这样,它会寻找你传入的特定对象,它不在集合中.

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

如果你的出发点是一个对象数组,你根本不需要Set,只需要Array.prototype.find:

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);

如果你已经有一个 Set 并且想要搜索它的匹配项,你可以使用它的迭代器,或者直接通过 for-of:

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);

...或间接通过Array.from来(重新)创建(the)一个数组,然后使用find:

...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);

您甚至可以将它放在 Set.prototype 上(确保它是不可枚举的),但要注意与将来添加到 Set 的内容冲突(例如,我会如果 Set.prototype 在某个时候得到了 find 方法,一点也不感到惊讶.

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).

相关文章