2017-07-29 92 views
1

是否可以使用javascript「Set」對象來查找具有某個鍵的元素? 類似的東西:JavaScript在一組中搜索對象鍵

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

回答

5

不是那樣的,那會找你傳遞的特定對象,這是不是在設定的。

如果你的出發點是對象的數組,你並不需要一個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);

如果你已經有了一個Set,並希望搜索對於匹配,您可以使用其迭代器,直接通過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間接(重新)創造(的)一個數組,然後用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方法)。

+0

謝謝您的回答,我的問題只是出於好奇,因爲我已經讀的地方,尋找一個'Set'對象具有O(1)的複雜性。 –

+0

*檢查是否在它*!== *搜索* –

+0

@Jonasw:真的! Alexandre,如果你只是想要一個布爾結果,使用上面的'some'而不是'find'(並相應地調整'for-of')。 –

5

你可能只是想將一組名稱:

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

如果你想通過名字得到一個對象,那是什麼一個地圖是:

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")); 
+1

雖然'Map'有效,這是* set *的用途:'let mySet = new Set(myObjects.map(e => e.name)); console.log(mySet.has(「a」));(如果我們要這樣解決它)。 –

1

簡短的回答 - 沒有。 Set.has在對象相等上運行,並且列表中的每個對象都是唯一的 - 因此,當您將新對象傳遞到.has時,即使它具有相同的鍵和值,也不會返回true

您可以隨時過濾原始列表,如果結果列表的長度大於零,則您的對象將包含在內。

const containsObjectWithName = ({ name }) => 
    !!myObjects 
    .filter((obj) => obj.name === name) 
    .length; 

containsObjectWithName({ name: 'a' }); // true 
2

如果你想用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

+0

這不符合OP的要求。這個問題很明顯有兩個單獨的對象(一個在數組中,一個**不同的**被搜索),而不是單個對象。 –