是否可以使用Javascript中的“Set”对象来查找具有特定键的元素?类似这样:
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"}));
是否可以使用Javascript中的“Set”对象来查找具有特定键的元素?类似这样:
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"}));
不是那样,那将搜索您传递的特定对象,而该对象不在集合中。
如果您的起点是一个对象数组,则根本不需要Set
,只需使用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);
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
直接或间接地重新创建数组,然后使用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);
如果这是你需要经常做的事情,你可以为自己创建一个实用函数:
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
方法,我一点也不惊讶)。
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"));
如果您想通过名称获取对象,那么 Map 就是为此而设计的:
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"));
Map
可以工作,但这就是 set 的用途:let mySet = new Set(myObjects.map(e => e.name)); console.log(mySet.has("a"));
(如果我们要用这种方式解决它)。 - T.J. Crowder如果您想使用Set来实现这个功能,那么您要查找的对象必须是添加的相同对象,而不是匿名对象。
因此,如果设置如下,您可以实现您所需的功能:
let myObject = {"name": "a", "value": 0};
let set = new Set([myObject]);
console.log(set.has(myObject));
set.has()
在底层使用了SameValueZero()
。set.has()
的规范: http://www.ecma-international.org/ecma-262/6.0/#sec-set.prototype.has SameValueZero()
的规范: http://www.ecma-international.org/ecma-262/6.0/#sec-samevaluezero
const containsObjectWithName = ({ name }) =>
!!myObjects
.filter((obj) => obj.name === name)
.length;
containsObjectWithName({ name: 'a' }); // true
var myObj = { "A": "1", "B": "2", "C": "3" }
var objLength = Object.keys(myObj).length
var firstKeyOfObject = Object.keys(myObj)[0]
var firstValueOfObject = myObj[Object.keys(myObj)[0]]
var lastKeyOfObject = Object.keys(myObj)[objLength - 1]
var lastValueOfObject = myObj[Object.keys(myObj)[objLength - 1]]
console.log('firstKeyOfObject', firstKeyOfObject)
console.log('firstValueOfObject', firstValueOfObject)
console.log('lastKeyOfObject', lastKeyOfObject)
console.log('lastValueOfObject', lastValueOfObject)
实际上是对如何高效地在Set中查找元素的回复,但他们将其关闭了,标记为重复问题#ftw
另一种方法:
class ArraySet extends Set {
find(predicate) {
for(var x of this)
if (predicate(x)) return x;
return undefined;
},
... other Array.prototype stuff here
}
const things = new ArraySet([
{ x: 1 },
{ y: 2 }
]);
const found = things.find(item => item.y === 2);
如果您希望您的解决方案具有高性能,请使用Map
而不是Set
。
如果您的Set
不是很大,您可以采用T.J. Crowder solution的方法,将Set
转换为Array
,然后进行筛选,反之亦然。
let myObjects = [['a',{"name":"a", "value":0}], ['b',{"name":"b", "value":1}],['c',{"name":"c", "value":2}]];
let myMap = new Map(myObjects);
console.log(myMap.has('a'));
Set
对象中搜索的复杂度为O(1)。 - Alexandre Sengessome
而不是上面的find
(并相应地调整for-of
)。 - T.J. Crowdernew Set([1, 2, 3])
),你不需要原始项目,因为2 === 2
,但是对于对象,你不能这样做,因为{} !== {}
。如果没有原始对象的引用,你无法在O(1)的时间复杂度内查找集合中任意对象的任意属性...此时你不需要在集合中查找它。 - VLAZ