जावास्क्रिप्ट में एक सेट बनाने के तरीके?


83

एलोकेंट जावास्क्रिप्ट, चैप्टर 4 में, वैल्यू का एक सेट एक ऑब्जेक्ट बनाकर वैल्यूज़ को प्रॉपर्टी के नाम के रूप में स्टोर किया जाता है, प्रॉपर्टी वैल्यूज़ के रूप में मनमाना वैल्यूज़ (जैसे सच) असाइन किया जाता है। यह जांचने के लिए कि क्या मूल्य पहले से ही सेट में निहित है, inऑपरेटर का उपयोग किया जाता है:

var set = {};

if (!'Tom' in set) { 
  set.Tom = true;
}

क्या यह मुहावरेदार जावास्क्रिप्ट है? एक सरणी का उपयोग भी बेहतर नहीं होगा?

var set = [];

if (!'Tom' in set) { 
  set.push = 'Tom';
}

1
आप किसी ऐसे ऐरे की उम्मीद कैसे करेंगे जिसके 'Tom' in setलिए दिखने में सच है? ऐसा लगता है कि आपके पास किसी चीज के बारे में गलत धारणाएं हैं , और मैं इस बारे में पता लगाने की कोशिश कर रहा हूं ।

10
FYI करें, आप कोष्ठक की जरूरत है: if(!('Tom' in set))। वर्तमान में इसका मतलब false in setहै !'Tom' === false
pimvdb

ES6 में सेट है, नीचे जॉन का जवाब देखें
बेन टालिडोरोस

जवाबों:


101

सेट अब ES2015 (उर्फ ES6, यानी ECMAScript 6) में उपलब्ध हैं। ES6 जून 2015 से जावास्क्रिप्ट के लिए वर्तमान मानक है।

ECMAScript 6 में डेटा संरचना सेट है जो मनमाने मूल्यों के लिए काम करती है, तेज है और NaN को सही ढंग से संभालती है। - एक्सल Rauschmayer , तलाश ES6

एक्सल रौशमायर की पुस्तक एक्सप्लोरिंग ईएस 6 से पहले दो उदाहरण :

एकल तत्वों का प्रबंधन:

> let set = new Set();
> set.add('red')

> set.has('red')
true
> set.delete('red')
true
> set.has('red')
false

सेट का आकार निर्धारित करना और उसे साफ़ करना:

> let set = new Set();
> set.add('red')
> set.add('green')

> set.size
2
> set.clear();
> set.size
0

यदि आप जावास्क्रिप्ट में समूह के बारे में अधिक जानना चाहते हैं, तो मैं ईएस 6 की खोज करूंगा । पुस्तक ऑनलाइन पढ़ने के लिए स्वतंत्र है, लेकिन यदि आप लेखक डॉ। एक्सल रौशमायर का समर्थन करना चाहते हैं, तो आप लगभग 30 डॉलर में पुस्तक खरीद सकते हैं।

यदि आप सेट्स और ES6 का उपयोग करना चाहते हैं, तो अब आप Babel , ES6 से ES5 ट्रांसपिलर, और इसके पॉलीफिल का उपयोग कर सकते हैं ।

संपादित करें: 6 जून, 2017 तक अधिकांश प्रमुख ब्राउज़रों को अपने नवीनतम संस्करणों (IE 11 को छोड़कर) में पूर्ण सेट समर्थन प्राप्त है। इसका मतलब है कि यदि आपको पुराने ब्राउज़रों का समर्थन करने की परवाह नहीं है तो आपको बैबल की आवश्यकता नहीं हो सकती है। यदि आप अपने वर्तमान ब्राउज़र सहित विभिन्न ब्राउज़रों में संगतता देखना चाहते हैं, तो कंगैक्स के ES6 संगतता तालिका की जांच करें ।

संपादित करें:

बस आरंभीकरण पर स्पष्टीकरण। सेट उनके निर्माता में किसी भी तुल्यकालिक पुनरावृत्ति ले सकते हैं। इसका मतलब है कि वे न केवल सरणियां ले सकते हैं, बल्कि तार, और पुनरावृत्तियां भी ले सकते हैं। उदाहरण के लिए एक सेट के निम्नलिखित सरणी और स्ट्रिंग आरंभीकरण के लिए लें:

const set1 = new Set(['a','a','b','b','c','c']);
console.log(...set1);
console.log(set1.size);
const set2 = new Set("aabbcc");
console.log(...set2);
console.log(set2.size);

सरणी और स्ट्रिंग के दोनों आउटपुट समान हैं। ध्यान दें कि ...set1है प्रसार वाक्य रचना । ऐसा प्रतीत होता है कि पुनरावृत्ति के प्रत्येक तत्व को एक-एक करके सेट में जोड़ा जाता है, इसलिए चूंकि सरणी और स्ट्रिंग दोनों में समान तत्व होते हैं और चूंकि तत्व एक ही क्रम में होते हैं, इसलिए सेट समान बनाया जाता है। सेट के बारे में ध्यान देने योग्य एक और बात यह है कि जब उन पर पुनरावृति क्रम उस आदेश का पालन करता है जो तत्वों को सेट में डाला गया था। यहाँ एक सेट पर पुनरावृत्ति का एक उदाहरण है:

const set1 = new Set(['a','a','b','b','c','c']);
for(const element of set1) {
  console.log(element);
}

चूँकि आप किसी सेट को इनिशियलाइज़ करने के लिए किसी भी iterable का उपयोग कर सकते हैं, यहाँ तक कि आप जनरेटर फंक्शन से भी itter इस्तेमाल कर सकते हैं । इटरेटर इनिशियलाइज़ेशन के दो ऐसे उदाहरण हैं जो समान आउटपुट का उत्पादन करते हैं:

// a simple generator example
function* getLetters1 () {
  yield 'a';
  yield 'a';
  yield 'b';
  yield 'b';
  yield 'c';
  yield 'c';
}

// a somewhat more commonplace generator example
// with the same output as getLetters1.
function* getLetters2 (letters, repeatTimes) {
  for(const letter of letters) {
    for(let i = 0; i < repeatTimes; ++i) { 
      yield letter;
    }
  }
}

console.log("------ getLetters1 ------");
console.log(...getLetters1());
const set3 = new Set(getLetters1());
console.log(...set3);
console.log(set3.size);

console.log("------ getLetters2 ------");
console.log(...getLetters2('abc', 2));
const set4 = new Set(getLetters2('abc', 2));
console.log(...set4);
console.log(set4.size);

इन उदाहरणों के जनरेटर फ़ंक्शन को केवल दोहराने के लिए नहीं लिखा जा सकता है, लेकिन अगर जनरेटर फ़ंक्शन अधिक जटिल है और जब तक कि निम्नलिखित प्रदर्शन को भी नकारात्मक रूप से प्रभावित नहीं करता है, तो आप जनरेटर से केवल मान प्राप्त करने में मदद करने के लिए सेट विधि का उपयोग कर सकते हैं जो डॉन नहीं करते हैं 'दोहरा नहीं।

यदि आप डॉ। रौशमायर के उनकी पुस्तक के अध्याय को पढ़े बिना सेट के बारे में अधिक जानना चाहते हैं, तो आप सेट पर एमडीएन डॉक्स देख सकते हैं । MDN भी इस तरह के का उपयोग कर के रूप में एक सेट पर बार-बार दोहराना के अधिक उदाहरण है forEachऔर का उपयोग कर .keys, .valuesऔर .entriesतरीकों। एमडीएन में सेट यूनियन, सेट चौराहा, सेट अंतर, सममित सेट अंतर और सेट सुपरसेट चेकिंग जैसे उदाहरण भी हैं। उम्मीद है कि उन कार्यों में से अधिकांश आपके समर्थन में अपने स्वयं के कार्यों का निर्माण करने की आवश्यकता के बिना जावास्क्रिप्ट में उपलब्ध हो जाएंगे। वास्तव में, नए सेट के तरीकों के लिए यह TC39 प्रस्ताव है, जो उम्मीद करता है कि प्रस्ताव 4 चरण में पहुंचने पर समय में कुछ भविष्य के बिंदु पर जावास्क्रिप्ट में सेट करने के लिए निम्न विधियों को जोड़ना चाहिए:

  • Set.prototyp.intersection (iterable) - विधि सेट चौराहे ऑपरेशन द्वारा नया सेट उदाहरण बनाता है।
  • Set.prototype.union (iterable) - विधि सेट यूनियन ऑपरेशन द्वारा नया सेट इंस्टेंस बनाता है।
  • Set.prototype.difference (iterable) - विधि पुनरावृति में मौजूद तत्वों के बिना नया सेट बनाता है।
  • Set.prototyp.symmetricDifference (iterable) - रिटर्न तत्वों का सेट केवल या तो इसमें या पुनरावृत्ति में पाया जाता है।
  • Set.prototype.isSubsetOf (iterable)
  • Set.prototype.isDisjointFrom (iterable)
  • Set.prototype.isSupersetOf (iterable)

सेट का स्वयं भी चलने योग्य है, इसलिए आप एक यूनियन ऑपरेशन के लिए एक सेट बनाने के लिए अन्य सेट के साथ नए सेट ([... setA, ... setB]) जैसे कुछ कर सकते हैं।
जॉन

1
@LanceKind मैंने कुछ अतिरिक्त जानकारी दी है जिसमें यह दर्शाया गया है कि आप सेट को केवल एरेज़ेबल के साथ सेट कर सकते हैं।
जॉन

32

मैं सेट के रूप में प्रमुख वस्तुओं का उपयोग करता हूं। यह स्ट्रिंग्स और संख्याओं के साथ काम करता है, लेकिन मुझे लगता है कि अगर आप कस्टम समानता और तुलनात्मक संचालकों का उपयोग करके वस्तुओं का एक सेट चाहते हैं तो समस्याएँ पैदा होंगी:

एक सेट बनाना:

var example_set = 
{
    'a':true,
    'b':true,
    'c':true
}

एक सेट में शामिल करने के लिए परीक्षण

if( example_set['a'] ){
    alert('"a" is in set');
}

एक सेट में एक तत्व जोड़ना

example_set['d'] = true;

एक सेट से एक तत्व को निकालना

delete example_set['a'];


1
जिस कोड पर मैं काम कर रहा था वह इंजन के पुराने संस्करण का उपयोग कर रहा था जिसके लिए समर्थन नहीं था Set। इससे मदद मिली।
अभिजित माधव

16

सेट डुप्लिकेट प्रविष्टियों की अनुमति नहीं देते हैं और आमतौर पर पूर्वनिर्धारित आदेश की गारंटी नहीं देते हैं। Arrays इन दोनों को करता है, इस प्रकार उल्लंघन करता है कि इसका एक सेट होने का क्या मतलब है (जब तक कि आप अतिरिक्त जांच न करें)।


2
Array डुप्लिकेट प्रविष्टियों को फ़िल्टर नहीं करता ... उदाहरण के लिए arr.push ({id: 1, name: "Jake"}) जैसे NSSet in Objective-C :)
iTux

यदि आप इसे मोट-ए-इंस्पेक्शन लेते हैं, तो नहीं। लेकिन आप बस आईडी (मानचित्र) कुंजी के रूप में आईडी का उपयोग कर सकते हैं। arr[id] = {"name": "Jake"};
भैंस

11

पहला तरीका मुहावरेदार जावास्क्रिप्ट है।

जब भी आप किसी कुंजी / मान युग्म को संग्रहीत करना चाहते हैं, तो आपको एक जावास्क्रिप्ट ऑब्जेक्ट का उपयोग करना होगा। सरणियों के लिए, कई समस्याएं हैं:

  1. सूचकांक एक संख्यात्मक मूल्य है।

  2. यह देखने का कोई आसान तरीका नहीं है कि यह देखने के लिए कि किसी ऐरे में कोई मान है या नहीं।

  3. एक सेट डुप्लिकेट की अनुमति नहीं देता है। एक सरणी करता है।


संपत्ति के मूल्य को निर्दिष्ट करने के लिए सबसे अच्छा क्या होगा?
हेल्परमेथोड

1
जावास्क्रिप्ट सरणियों से डुप्लिकेट तत्वों को निकालना संभव है। stackoverflow.com/a/12166248/975097
एंडरसन ग्रीन

9

यदि आप किसी सरणी से एक सेट बनाना चाहते हैं, तो बस यह करें:

let arr = [1, 1, 2, 1, 3];
let mySet = new Set(arr); // Set { 1, 2, 3 }

यह एक चीनी वाक्य रचना है जिसे मैं पायथन में प्रोग्रामिंग करते समय काफी पसंद करता हूं, इसलिए खुशी है कि ईएस 6 ने आखिरकार वही काम करना संभव बना दिया।

ध्यान दें: तब मुझे एहसास होता है कि मैंने जो कहा वह आपके सवाल का सीधा जवाब नहीं था। ES5 में आपके पास यह "हैक" करने का कारण यह है क्योंकि कुंजियों द्वारा किसी वस्तु में देखने का समय सरणी (O (n)) की तुलना में काफी तेज (O (1)) है। प्रदर्शन महत्वपूर्ण अनुप्रयोगों में, आप बेहतर प्रदर्शन के लिए इस पठनीयता या अंतर्ज्ञान का त्याग कर सकते हैं।

लेकिन हे, 2017 में आपका स्वागत है, जहां आप सभी प्रमुख आधुनिक ब्राउज़रों में उचित सेट का उपयोग कर सकते हैं!


6

में सेट ES6/ ES2015:

ES6/ ES2015अब सेट में बनाया गया है। एक सेट डेटा संरचना है जो किसी भी प्रकार के अनूठे मूल्यों के भंडारण की अनुमति देता है, चाहे यह आदिम मूल्य या वस्तु संदर्भ हो। ES6निम्नलिखित तरीके से निर्मित सेट का उपयोग करके एक सेट घोषित किया जा सकता है:

const set = new Set([1, 2, 3, 4, 5]);

सेट कंस्ट्रक्टर का उपयोग करके एक सेट बनाते समय हमारी नई बनाई गई सेट ऑब्जेक्ट सेट से विरासत में मिलती है Set.prototype। इसमें सभी प्रकार के सहायक तरीके और गुण हैं। यह आपको निम्नलिखित चीजों को आसानी से करने की अनुमति देता है:

उदाहरण:

const set = new Set([1, 2, 3, 4, 5]);

// checkout the size of the set
console.log('size is: ' + set.size);

// has method returns a boolean, true if the item is in the set
console.log(set.has(1));

// add a number
set.add(6);

// delete a number
set.delete(1);

// iterate over each element using a callback
set.forEach((el) => {
  console.log(el);
});

// remove all the entries from the set
set.clear();

ब्राउज़र संगतता:

सभी प्रमुख ब्राउज़र अब IE को छोड़कर पूरी तरह से सेट का समर्थन करते हैं जहां कुछ सुविधाएँ गायब हैं। सटीक संदर्भ के लिए कृपया mdn डॉक्स देखें ।


@ वेलोजेट: ठीक है, काफी उचित।
kjhughes

3

सेट का अनुकरण करने के लिए नंगे जावास्क्रिप्ट वस्तुओं का उपयोग करने के साथ दो समस्याएं हैं: पहला, एक वस्तु में एक विरासत में मिली संपत्ति हो सकती है जो "ऑपरेटर" में पेंच करेगी और दूसरा, आप केवल स्केलर मान को इस तरह स्टोर कर सकते हैं, वस्तुओं का एक सेट नहीं है। मुमकिन। इसलिए, सेटों का एक यथार्थवादी कार्यान्वयन तरीकों को प्रदान करना चाहिए addऔर containsइसके बजाय सादा inऔर संपत्ति असाइनमेंट करना चाहिए।


@ कोकोजी: वस्तुओं को कुंजी के रूप में उपयोग किए जाने पर तार में परिवर्तित किया जाता है:set={};set[{x:1}]=123;alert(set[{z:99}])
जॉर्ज

3

आप बाल्टी की कोशिश कर सकते हैं , एक जावास्क्रिप्ट डेटा संरचना पुस्तकालय है और आपके पास सेटों में हेरफेर करने के लिए आवश्यक सब कुछ है।


क्या यह एक addAll (सरणी) विधि प्रदान करता है?
जोरेबोर

1

सेट ऑब्जेक्ट का मूल निर्माण और उपयोग Set

let mySet = new Set()

mySet.add(2)         // Set {2}
mySet.add(7)         // Set {2, 7}
mySet.add(7)         // Set {2, 7}
mySet.add('my text') // Set {2, 7, 'my text'}
let myObj = { a: 1, b: 2 }
mySet.add(myObj)     // Set {2, 7, 'my text', {...}}
mySet.has(2)         // true
mySet.has(myObj)     // true
mySet.size           // 4

यात्रा

for (let item of mySet) console.log(item)  // 2, 7, 'my text', {a:1, b:2}
mySet.forEach(value => console.log(value)) // 2, 7, 'my text', {a:1, b:2}

सरणी में कनवर्ट करें

var myArr = Array.from(mySet)             // [2, 7, 'my text', {a:1, b:2}]

Object सबसे अलग सुविधा सेट ऑफ़र सेट ऑब्जेक्ट में प्रत्येक मूल्य अद्वितीय होना चाहिए। इसलिए आप डुप्लिकेट मान नहीं जोड़ सकते हैं।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.