2010-08-08 13 views
8

मैं जावास्क्रिप्ट में एक बड़ा सा क्षेत्र बनाना चाहता हूं जो प्रभावी रूप से मार्करों की बहु-आयामी सरणी का प्रतिनिधित्व करेगा (भौतिक "1 डी" संरचना में विभिन्न आयामों पर कूदने के लिए अनुक्रमण का उपयोग करता है)।एक बड़ा सा क्षेत्र बनाएँ?

संख्याओं के समूह की बजाय, मैं इस बात पर विचार कर रहा हूं कि मैं बिट्स के रूप में स्ट्रिंग का उपयोग कैसे कर सकता हूं, इसलिए मैं पहले उचित लंबाई की एक स्ट्रिंग आवंटित कर सकता हूं। डेटा प्रकार, यूनिकोड और रूपांतरण जैसे विचार खेल में आते हैं (जावास्क्रिप्ट 1.3 से पहले कोई यूनिकोड समर्थन भी नहीं)।

हालांकि मैं अन्य सुझावों के बारे में खुला हूं कि बड़े क्षेत्र को प्राप्त करने के लिए जावास्क्रिप्ट का उपयोग कैसे करें।

अद्यतन:
बस सूचना के प्रयोजनों के लिए: औसत पर मैं का उपयोग कर रहा हो सकता है ~ 2187 बिट्स/मार्कर (274 बाइट्स), लेकिन एक सामान्य जवाब से बहुत अधिक बिट्स समायोजित कर सकते हैं करना चाहते हैं।

+0

संख्याओं का उपयोग क्यों नहीं किया जा सकता है? आप 1 से अधिक अंकों का उपयोग कर सकते हैं, आपको पता है? – Oded

+0

@ ओडेड: मैंने नहीं कहा कि संख्याओं का उपयोग नहीं किया जा सकता - "अन्य सुझावों के बारे में खुला" स्ट्रिंग सिर्फ एक विचार है। जवाब के लिए तत्पर हैं। –

उत्तर

12

एक समस्या यह है कि वे अडिग हैं, तो आप कुछ भी बदलना चाहते हैं, तो आप स्ट्रिंग के पुनर्निर्माण की जरूरत होती है।

मैं सिर्फ संख्याओं का उपयोग करने के लिए चिपक गया होगा। बिटवाई ऑपरेटरों का उपयोग करके, आप प्रत्येक नंबर में 32 बिट फिट कर सकते हैं।

आप 53 बिट्स तक फिट कर सकते हैं, क्योंकि जावास्क्रिप्ट नंबर डबल-प्रेसिजन फ्लोटिंग पॉइंट हैं, लेकिन बिटवाई ऑपरेटर्स अपने ऑपरेटरों को 32-बिट पूर्णांक में परिवर्तित करते हैं, इसलिए आप व्यक्तिगत रूप से प्राप्त करने के लिए उनका उपयोग नहीं कर पाएंगे बिट्स (यदि आप चाहते थे, तो आप विभाजन के संयोजन, Math.pow इत्यादि के साथ एक ही चीज़ को पूरा कर सकते हैं, लेकिन यह अधिक जटिल होगा)।

यहाँ एक बुनियादी कार्यान्वयन आप प्राप्त करने देता है कि, सेट है, और सेट किए बिना अलग-अलग बिट्स:

function BitField() { 
    this.values = []; // You could set the length here, but it's not necessary 
} 

BitField.prototype.get = function(i) { 
    var index = (i/32) | 0; // | 0 converts to an int. Math.floor works too. 
    var bit = i % 32; 
    return (this.values[index] & (1 << bit)) !== 0; 
}; 

BitField.prototype.set = function(i) { 
    var index = (i/32) | 0; 
    var bit = i % 32; 
    this.values[index] |= 1 << bit; 
}; 

BitField.prototype.unset = function(i) { 
    var index = (i/32) | 0; 
    var bit = i % 32; 
    this.values[index] &= ~(1 << bit); 
}; 
+0

यह अच्छी तरह से काम करता है। –

+0

बहुत बढ़िया, सरल कार्यान्वयन! क्या आप [मेरा विस्तार] (http://stackoverflow.com/a/25807014/2228771) पर एक नज़र डालेंगे? – Domi

-1

क्रोम में, मुझे लगभग 10,000 बिट मिलते हैं। तार के साथ

var bitfield = 0; 
var flag1 = 2 << 1; 
var flag2 = 2 << 2; 
var flagmax = 2 << 10000; 
bitfield |= flagmax 
if (bitfield & flagmax) { 
    doSomething(); 
} 
+0

मैं देखता हूं। आपने बस मेरी धारणा को उड़ा दिया कि बिट स्थानांतरण को नियोजित करते समय संख्या का आकार स्थिर रहता है। अच्छी चीज़। –

+0

जावास्क्रिप्ट में बिटवाई ऑपरेटरों केवल 32 बिट्स के साथ काम करते हैं, इसलिए '2 << 10000' ओवरफ्लो, और' 2 << 16' के बराबर है। –

+0

@ मैथ्यू सी जानना अच्छा है - मैंने उपरोक्त सोचने से नहीं रोक दिया कि यह एक अनचाहे प्रयास हो सकता है। –

4

हाल ब्राउज़रों में, कुशल संख्यात्मक सरणी प्रकार उपलब्ध हैं। कोई बिट-सरणी नहीं है, लेकिन आप Uint8Array या Uint32Array का उपयोग कर सकते हैं और बिट्स को स्वयं पैक कर सकते हैं (मैथ्यू क्रूमली के उत्तर के समान ही, [] के बजाय एक संख्यात्मक सरणी का उपयोग करें)।


obselete लेकिन बराबर जवाब (CanvasPixelArrayUint8ClampedArray द्वारा प्रतिस्थापित किया गया):

ब्राउज़र आप का समर्थन करता है <canvas> लक्षित कर रहे हैं, तो आप एक CanvasPixelArray वस्तु (canvas.getContext("2d").createImageData(...).data उधार सकता है; ध्यान दें कि यह जरूरत नहीं कैनवास के समान आकार) (उम्मीद है) मेमोरी-कुशलता से डेटा स्टोर (प्रत्येक तत्व एक ऑक्टेट है)। और यदि आपका डेटा 2 डी है, तो आप मुफ्त में विज़ुअलाइज़ेशन प्राप्त कर सकते हैं!

+0

+1 मुझे यह पसंद है लेकिन अभी तक HTML 5 के अनुरूप नहीं हो सकता है। रचनात्मक समाधान के लिए धन्यवाद। –

3

यह 2010 से Matthew Crumley's post के लिए एक विस्तार है:

मैं मैथ्यू के कोड लिया, पूर्व आवंटन को जोड़ कर उसे तुलना सरणी कार्यान्वयन लिखे गए।

This jsperf दिखाता है कि क्रोम सबसे तेज़ और संवेदनात्मक है (मैं सबसे तेज़ प्रदर्शन करने के लिए Uint32Array की अपेक्षा करता हूं) और आईई ने केवल इंटरफेस को परिभाषित किया लेकिन टाइप किए गए सरणी को अनुकूलित करने की परवाह नहीं की। फ़ायरफ़ॉक्स के परिणाम अस्पष्ट हैं क्योंकि कंसोल को चेतावनी के साथ बाढ़ आ गई है कि JSPerf परीक्षण कोड को "संकलित" कैसे करता है।

enter image description here

Uint8Array कार्यान्वयन ("अन्य" मेरी जाहिरा तौर पर बहुत ही निजी) आईई 11. है()

function BitField8(nSize) { 
    var nBytes = Math.ceil(nSize/8) | 0; 
    this.values = new Uint8Array(nBytes); 
} 

BitField8.prototype.get = function(i) { 
    var index = (i/8) | 0; 
    var bit = i % 8; 
    return (this.values[index] & (1 << bit)) !== 0; 
}; 

BitField8.prototype.set = function(i) { 
    var index = (i/8) | 0; 
    var bit = i % 8; 
    this.values[index] |= 1 << bit; 
}; 

BitField8.prototype.unset = function(i) { 
    var index = (i/8) | 0; 
    var bit = i % 8; 
    this.values[index] &= ~(1 << bit); 
}; 

Uint32Array कार्यान्वयन

function BitField32(nSize) { 
    var nNumbers = Math.ceil(nSize/32) | 0; 
    this.values = new Uint32Array(nNumbers); 
} 

BitField32.prototype.get = function(i) { 
    var index = (i/32) | 0; 
    var bit = i % 32; 
    return (this.values[index] & (1 << bit)) !== 0; 
}; 

BitField32.prototype.set = function(i) { 
    var index = (i/32) | 0; 
    var bit = i % 32; 
    this.values[index] |= 1 << bit; 
}; 

BitField32.prototype.unset = function(i) { 
    var index = (i/32) | 0; 
    var bit = i % 32; 
    this.values[index] &= ~(1 << bit); 
}; 
संबंधित मुद्दे