Tuples से जावास्क्रिप्ट चर कार्य


99

पायथन 2 और पायथन 3 जैसी अन्य भाषाओं में, आप टपल वैरिएबल के मानों को परिभाषित और असाइन कर सकते हैं, और उनके मूल्यों को इस तरह से पुनः प्राप्त कर सकते हैं:

tuple = ("Bob", 24)
name, age = tuple
print(name)           #name evaluates to Bob
print(age)            #age evaluates to 24

क्या जावास्क्रिप्ट में भी ऐसा ही कुछ है? या क्या मुझे सिर्फ एक सरणी के साथ इसे बदसूरत तरीके से करना है:

tuple = ["Bob", 24]
name = tuple[0]       //name Evaluates to Bob
age = tuple[1]        //age Evaluates to 24

क्या जावास्क्रिप्ट 5 में पायथन टुपल्स को अनुकरण करने का एक बेहतर तरीका है?

अपडेट: ईएस 6 के बारे में जवाब देखें, जिसे नए प्रोजेक्ट्स के लिए कॉफीस्क्रिप्ट पर पसंद किया जाना चाहिए।


12
जावास्क्रिप्ट में, चर घोषित करने के लिए मत भूलना:var tuple, name, age;
.ime Vidas

3
var name=tuple[0], age=tuple[1]; यह थोड़ा अधिक टाइपिंग है, लेकिन बदसूरत एक ओवरस्टेटमेंट हो सकता है।
ब्रेंट बर्नबर्न

जवाबों:


120

जावास्क्रिप्ट 1.7 ने विनाशकारी असाइनमेंट जोड़ा जो आपको अनिवार्य रूप से करने की अनुमति देता है कि आप क्या हैं।

function getTuple(){
   return ["Bob", 24];
}
var [a, b] = getTuple();
// a === "bob" , b === 24 are both true

5
यह मानक-आधारित जावास्क्रिप्ट नहीं है, बल्कि मोज़िला-विशिष्ट एक्सटेंशन है।
निन्जाएजेको

14
@ninjagecko: "जावास्क्रिप्ट" मोज़िला का कार्यान्वयन है, और विनाशकारी असाइनमेंट आने वाले पारिस्थितिकी मानक का हिस्सा होंगे
बर्गी

64
यह अब वास्तव में ES6 का हिस्सा है।
पियर पाओलो रेमन

9
कुछ वर्षों को देखते हुए मेरा उत्तर तकनीकी रूप से सही हो गया है लेकिन सही और सहायक दोनों के लिए उपयोगी नहीं है। वाह!
pc1oad1etter

49

आपको इसे बदसूरत तरीके से करना होगा। यदि आप वास्तव में ऐसा कुछ चाहते हैं, तो आप कॉफीस्क्रिप्ट की जांच कर सकते हैं , जिसमें वह और कई अन्य विशेषताएं हैं जो इसे अधिक दिखती हैं जैसे कि अजगर (खेद है कि यह एक विज्ञापन की तरह ध्वनि बनाने के लिए है, लेकिन मैं वास्तव में इसे पसंद करता हूं।)


हम्म, यह काफी दिलचस्प है, बस इस परिदृश्य पर अपने आप भाग गया, क्योंकि जावास्क्रिप्ट स्पष्ट टपल समर्थन प्रदान नहीं करता है, और कार्यात्मक प्रोग्रामिंग की तीव्र अवधि से आ रहा है, आप ट्यूपल्स के लिए इच्छा विकसित करते हैं। मुझे भी बस यही मिला, लेकिन यकीन नहीं होता कि यह काम करता है, यह सिर्फ टपल समर्थन के मामले में भी अच्छा लग रहा था: cs.umd.edu/projects/PL/arrowlets/api-tuples.xhtml । मैं निश्चित रूप से CoffeeScript को देखूंगा।
9codeMan9

29

आप कुछ ऐसा ही कर सकते हैं:

var tuple = Object.freeze({ name:'Bob', age:14 })

और फिर विशेषताओं के रूप में नाम और उम्र का संदर्भ दें

tuple.name 
tuple.age 

5
मैं नीचे नहीं जाऊंगा, लेकिन तकनीकी रूप से यह गलत है। ऑब्जेक्ट घोषित होने के बाद भी आप tuple.name और tuple.age के मानों को बदल सकते हैं (यानी म्यूट कर सकते हैं)। परिभाषा के अनुसार अपरिवर्तनीय प्रकारों को परिभाषित किए जाने के बाद गैर को बदला जा सकता है। वे रीड-ओनली प्रकारों की तरह हैं जहाँ दोनों पैरामीटर और उनके मान केवल एक बार घोषित किए जा सकते हैं
इवान प्लाइस

4
@EvanPlaice यदि उत्परिवर्तन एक मुद्दा है, तो आप उपयोग कर सकते हैं Object.freeze(), अर्थात:tuple = Object.freeze({ name:'Bob', age:14 })
कैनन

@canon मैं सहमत हूँ, कि शायद इस पूरे धागे में केवल स्वीकार्य / सही दृष्टिकोण है। दुर्भाग्य से, mcm का उत्तर ऑब्जेक्ट को फ्रीज नहीं करता है इसलिए यह अभी भी परिवर्तनशील है।
इवान प्लाइस

@EvanPlaice मैं यह नहीं देखता कि उत्परिवर्तन का मुद्दा कहां से आया है - मूल पायथन उदाहरण में ट्यूप्स अपरिवर्तनीय नहीं हैं!
डैनियल बकमास्टर

@DanielBuckmaster पायथन में एक सूची और एक ट्यूपल के बीच का अंतर है, एक सूची परस्पर है जबकि एक ट्यूपल नहीं है। Docs.python.org/2/tutorial/… देखें । Tuples को जावास्क्रिप्ट में मूल रूप से समर्थित नहीं किया गया है क्योंकि सभी JS डेटा संरचना तब तक परिवर्तनशील होती हैं जब तक कि आप निर्माण के बाद ऑब्जेक्ट पर Object.freeze () को कॉल नहीं करते हैं।
इवान प्लाइस

27

यह "टपल" सुविधा इसे EcmaScript2015 में विनाशकारी कहा जाता है और जल्द ही इसे अद्यतित ब्राउज़रों द्वारा समर्थित किया जाता है। फिलहाल , केवल फ़ायरफ़ॉक्स और क्रोम इसका समर्थन करते हैं

लेकिन हे, आप एक ट्रांसपिलर का उपयोग कर सकते हैं ।

कोड अजगर के रूप में अच्छा लगेगा:

let tuple = ["Bob", 24]
let [name, age] = tuple

console.log(name)
console.log(age)

2
भविष्य के पाठकों के लिए: यह सुविधा क्रोम में क्रोम 49 (मोज़िला डॉक्स के अनुसार) के बाद से समर्थित है। आप मोज़िला डॉक्स का उपयोग करके संगतता की जाँच भी कर सकते हैं: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
जेमी

12

एक जमे हुए सरणी एक अजगर टपल को पहचानता है:

const tuple = Object.freeze(["Bob", 24]);
let [name, age]; = tuple
console.debug(name); // "Bob"
console.debug(age); // 24

फैंसी बनें और एक वर्ग को परिभाषित करें

class Tuple extends Array { 
  constructor(...items) { 
    super(...items); 
    Object.freeze(this);
  } 
}

let tuple = new Tuple("Jim", 35);
let [name, age] = tuple;
console.debug(name); // Jim
console.debug(age); // 35
tuple = ["Bob", 24]; // no effect 
console.debug(name); // Jim
console.debug(age); // 25

सभी नवीनतम ब्राउज़रों में आज काम करता है।


क्या आप इसे सिर्फ एक कास्ट के लिए सेट नहीं कर सकते हैं? कांस्टेबल अपरिवर्तनीय है, नहीं?
मार्क ए

2
सं। आश्वस्त नहीं है। आप नक्षत्र नहीं कर सकते हैं = ["जिम", ३५]; tuple = ["जेम्स", ३५]। आप कास्ट ट्यूपल कर सकते हैं = ["जिम", ३५]; tuple [0] = "जेम्स"; इसलिए यह अपरिवर्तनीय नहीं है।
मैथ्यू जेम्स डेविस

6

Tuples जावास्क्रिप्ट में समर्थित नहीं हैं

यदि आप एक अपरिवर्तनीय सूची की तलाश कर रहे हैं, तो Object.freeze () का उपयोग किसी सरणी को अपरिवर्तनीय बनाने के लिए किया जा सकता है।

ऑब्जेक्ट.फ़्रीज़ () विधि किसी ऑब्जेक्ट को जमा करती है: अर्थात, नए गुणों को इसमें जोड़े जाने से रोकता है; मौजूदा गुणों को हटाए जाने से रोकता है; और मौजूदा गुणों, या उनकी गणना, विन्यास, या लेखनीयता को बदलने से रोकता है। संक्षेप में वस्तु को प्रभावी रूप से अपरिवर्तनीय बनाया जाता है। विधि जमे हुए वस्तु को वापस करती है।

स्रोत: मोज़िला डेवलपर नेटवर्क - ऑब्जेक्ट.फ्रीज़ ()

किसी सरणी को हमेशा की तरह असाइन करें लेकिन 'Object.freeze () का उपयोग करके इसे लॉक करें

> tuple = Object.freeze(['Bob', 24]);
[ 'Bob', 24 ]

मानों का उपयोग करें क्योंकि आप एक नियमित सरणी (अजगर बहु-कार्य समर्थित नहीं है)

> name = tuple[0]
'Bob'
> age = tuple[1]
24

एक नया मान असाइन करने का प्रयास करें

> tuple[0] = 'Steve'
'Steve'

लेकिन मूल्य नहीं बदला है

> console.log(tuple)
[ 'Bob', 24 ]

साइड-नोट पर उम्मीद है कि ट्यूपल्स को ES6 में प्रथम श्रेणी का समर्थन मिलेगा। ट्रू देशी ट्यूपल (यानी विषम अनुक्रम) भी गति में सुधार करेगा।
इवान प्लाइस

5

दुर्भाग्यवश आप उस tuple असाइनमेंट सिंटैक्स को (ECMA | Java) स्क्रिप्ट में उपयोग नहीं कर सकते।

संपादित करें: किसी को मोज़िला / जेएस 1.7 से जोड़ा गया है - यह क्रॉस-ब्राउज़र काम नहीं करेगा लेकिन अगर इसकी आवश्यकता नहीं है, तो आपका जवाब है।


3

यह वास्तव में वास्तविक जीवन में उपयोग करने का इरादा नहीं है, बस एक दिलचस्प व्यायाम है। देखें कि जावास्क्रिप्ट एक्वल फ़ंक्शन का उपयोग एक बुरा विचार क्यों है? ब्योरा हेतु।

यह वह निकटतम है जो आप विक्रेता-विशिष्ट एक्सटेंशन का सहारा लिए बिना प्राप्त कर सकते हैं:

myArray = [1,2,3];
eval(set('a,b,c = myArray'));

सहायक समारोह:

function set(code) {
    var vars=code.split('=')[0].trim().split(',');
    var array=code.split('=')[1].trim();
    return 'var '+vars.map(function(x,i){return x+'='+array+'['+i+']'}).join(',');
}

प्रमाण है कि यह मनमाने दायरे में काम करता है:

(function(){
    myArray = [4,5,6];
    eval(set('x,y,z = myArray'));
    console.log(y);  // prints 5
})()

eval सफारी में समर्थित नहीं है।


5
+1 सुपर चालाक होने के लिए, कभी वास्तविक जीवन में इस का उपयोग नहीं करते, हालांकि :-P
Jamund फर्ग्यूसन

3

मंत्री के जवाब के अपडेट के रूप में, अब आप es2015 के साथ ऐसा कर सकते हैं:

function Tuple(...args) {
  args.forEach((val, idx) => 
    Object.defineProperty(this, "item"+idx, { get: () => val })
  )
}


var t = new Tuple("a", 123)
console.log(t.item0) // "a"
t.item0 = "b"
console.log(t.item0) // "a"

https://jsbin.com/fubaluwimo/edit?js,console


ऐसा कोई कारण नहीं है कि आप ES2015 से पहले ऐसा नहीं कर सकते हैं ... इसके अलावा यह ओपी के सवाल का जवाब नहीं देता, उन्होंने विनाश के लिए कहा
ThatWeirdo

3

आपके पास जावास्क्रिप्ट में एक टपल प्रकार भी हो सकता है। बस इसे उच्च क्रम के कार्यों (शैक्षणिक शब्द चर्च एन्कोडिंग) के साथ परिभाषित करें:

const Tuple = (...args) => {
  const Tuple = f => f(...args);
  return Object.freeze(Object.assign(Tuple, args));
};

const get1 = tx => tx((x, y) => x);

const get2 = tx => tx((x, y) => y);

const bimap = f => g => tx => tx((x, y) => Tuple(f(x), g(y)));

const toArray = tx => tx((...args) => args);

// aux functions

const inc = x => x + 1;
const toUpperCase = x => x.toUpperCase();

// mock data

const pair = Tuple(1, "a");

// application

console.assert(get1(pair) === 1);
console.assert(get2(pair) === "a");

const {0:x, 1:y} = pair;
console.log(x, y); // 1 a

console.log(toArray(bimap(inc) (toUpperCase) (pair))); // [2, "A"]

const map = new Map([Tuple(1, "a"), Tuple(2, "b")]);
console.log(map.get(1), map.get(2)); // a b

कृपया ध्यान दें कि Tupleएक सामान्य कंस्ट्रक्टर के रूप में उपयोग नहीं किया जाता है। समाधान प्रोटोटाइप सिस्टम पर बिल्कुल भी निर्भर नहीं करता है, बल्कि पूरी तरह से उच्च क्रम के कार्यों पर निर्भर करता है।

Tuples की Arrayतरह उपयोग किए गए tuples के फायदे क्या हैं ? चर्च एन्कोडेड ट्यूपल्स डिजाइन द्वारा अपरिवर्तनीय हैं और इस प्रकार उत्परिवर्तन के कारण होने वाले दुष्प्रभावों को रोकते हैं। यह अधिक मजबूत अनुप्रयोगों के निर्माण में मदद करता है। इसके अतिरिक्त, कोड के बारे में तर्क करना आसान है जो Arrayएक संग्रह प्रकार (उदाहरण के लिए [a]) और विभिन्न प्रकारों (जैसे (a, b)) के संबंधित डेटा के रूप में ट्यूपल्स के बीच अंतर करता है ।


1

यहाँ एक सरल जावास्क्रिप्ट टपल कार्यान्वयन है:

var Tuple = (function () {
   function Tuple(Item1, Item2) {
      var item1 = Item1;
      var item2 = Item2;
      Object.defineProperty(this, "Item1", {
          get: function() { return item1  }
      });
      Object.defineProperty(this, "Item2", {
          get: function() { return item2  }
      });
   }
   return Tuple;
})();

var tuple = new Tuple("Bob", 25); // Instantiation of a new Tuple
var name = tuple.Item1; // Assignment. name will be "Bob"
tuple.Item1 = "Kirk"; // Will not set it. It's immutable.

यह एक 2-ट्यूपल है, हालांकि, आप 3,4,5,6 आदि ट्यूपल्स का समर्थन करने के लिए मेरे उदाहरण को संशोधित कर सकते हैं।


वास्तव में यह एक टी-अप नहीं बल्कि एक जोड़ी है।
पियर पाओलो रेमन

tupleउदाहरण अभी भी परिवर्तनशील है, इसलिए यह तकनीकी रूप से एक टपल नहीं है। प्रूफ चेंज के लिए tuple.Item1 = "Steve"फिर console.log()आउटपुट।
इवान प्लाइस

1
कि खोजने के लिए धन्यवाद। मैंने टुपल को अपरिवर्तनीय बनाने के लिए उदाहरण को संशोधित किया है।
फारिस ज़सीना

मनमानी लंबाई का समर्थन करने के लिए आप इसे कैसे संशोधित करते हैं?
अज़

यह ओपी के सवाल का जवाब नहीं देता है, उन्होंने विनाश करने के लिए कहा
दैट वीर्डो

0

यहाँ मैथ्यू जेम्स डेविस के पायथन टपल तरीकों के उत्तर का एक संस्करण जोड़ा गया है:

class Tuple extends Array { 
  constructor(...items) { 
    super(...items); 
    Object.freeze(this);
  }
  toArray() {
    return [...this];
  }
  toString() {
    return '('+super.toString()+')';
  }
  count(item) {
    var arr = this.toArray();
    var result = 0;
    for(var i = 0; i < arr.length; i++) {
       if(arr[i] === item) {
         result++;
       }
    }
    return result;
  }

  

  
}

   let tuple = new Tuple("Jim", 35);
   let [name,age] = tuple;

console.log("tuple:"+tuple)
console.log("name:"+name)
console.log("age:"+age)

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