2008-09-18 25 views
10

मैं पर्ल में एक सरणी छोटा कैसे बना सकता हूं?मैं पर्ल में एक सरणी कैसे छोटा कर सकता हूं?

$#ARRAY = 42; 

मैंने पढ़ा है कि $ # के उपयोग अब मान्य नहीं है: मैं कुछ वेबपेजों यह दर्शाता है कि मैं प्रदान कर सकते हैं पढ़ें। मुझे एक ऐसे समाधान की आवश्यकता है जो सरणी की सरणी के लिए भी काम करेगी। यह काम नहीं किया:

$#$ARRAY[$i] = 42; 
+0

$ # हटाई गई है, लेकिन $ # $ # सरणी के रूप में ही नहीं है। मैंने कहीं भी नहीं पढ़ा है कि $ # सरणी को बहिष्कृत किया गया है, हालांकि यह भ्रमित है और मैं इसे इस्तेमाल करने के खिलाफ एक की सिफारिश करता हूं। –

उत्तर

16

मुझे $#ARRAY को बहिष्कृत करने के बारे में पता नहीं है; 5.10.0 से perldoc perldata निश्चित रूप से इसके बारे में कुछ भी नहीं कहता है। यह एक सरणी को छीनने का सबसे तेज़ तरीका है।

आप कुछ और भी अधिक पठनीय चाहते हैं, splice का उपयोग करें:

splice @ARRAY, 43; 

(नोट 43 बजाय 42 - $#ARRAY आप सरणी के अंतिम सूचकांक हो जाता है, जबकि splice taks सरणी के लंबाई बजाय)।

सरणी के सरणी पर काम करने के लिए, मुझे लगता है कि आप एक संदर्भ के माध्यम से एक नेस्टेड सरणी को छोटा करने में सक्षम होने का मतलब है?उस मामले में, आप चाहते हैं:

$#{$ARRAY->[7]} = 42; 

या

splice @{$ARRAY->[7]}, 43; 
0

आप के पास असीम

splice @array, $length; 
#or 
splice @{$arrays[$i]}, $length; 
+0

आपके दूसरे उदाहरण में आपके पास एक नकली बिंदु है। –

10

आपके विकल्प हैं कर सकता है (मैं पाँच दृष्टिकोण यहाँ रेखांकित किया है), लेकिन अपनी रणनीति वास्तव में अपने विशिष्ट जरूरतों और लक्ष्यों को क्या कर रहे हैं से तय की जाएगी। (सभी उदाहरण @array में परिवर्तित कर देंगे और नहीं एन से $ तत्वों के लिए)


[संपादित करें]

के रूप में अन्य लोगों ने बताया है, जिस तरह से मूल प्रश्न में सुझाव दिया वास्तव में पदावनत नहीं है, और यह सबसे तेज़, सबसे तेज़, लेकिन आवश्यक रूप से सबसे अधिक पढ़ने योग्य समाधान प्रदान करता है। यह भी खाली तत्वों के साथ से कम एन $ तत्वों की एक सरणी के विस्तार की ओर प्रभाव पड़ता है:

$#array = $N-1; 

कम से कम कोड:

#best for trimming down large arrays into small arrays 
@array = $array[0..($N-1)]; 

अधिकांश एक छोटी संख्या बंद ट्रिमिंग के लिए कुशल एक बड़ी सरणी:

#This is a little less expensive and clearer 
splice(@array, $n, @#array); 

लगभग एक में अवांछनीय ll मामलों, जब तक आप वास्तव में) को हटा (प्यार:

#this is the worst solution yet because it requires resizing after the delete 
while($N-1 < $#array) 
{ 
    delete(array[$i]); 
} 

उपयोगी यदि आप उलटे क्रम में सूची के शेष की जरूरत है:

#don't put more values into the array than you actually want 
: लंबे समय में समय की बचत के लिए

#this is better than deleting because there is no resize 
while($N-1 < $#array) 
{ 
    pop @array; 
    #or, "push $array2, pop @array;" for the reverse order remainder 
} 

उपयोगी

+0

वह तराजू बहुत बुरी तरह से, विशेष रूप से जब आपके सरणी में बहुत सारे तत्व होते हैं लेकिन केवल कुछ हटाते हैं। –

+0

अच्छा बिंदु। मैंने उस चेतावनी को शामिल करने के लिए मूल उत्तर का विस्तार किया और कुछ अन्य विकल्प प्रदान किए। – Frosty

2
  • $ # सरणी सरणी के पिछले सूचकांक है।
  • $ # $ array एक सरणी की अंतिम अनुक्रमणिका पर $ array द्वारा इंगित की जाएगी।
  • $ # $ सरणी [$ i] का अर्थ है कि आप एक स्केलर को अनुक्रमणित करने का प्रयास कर रहे हैं - नहीं किया जा सकता है। अंतिम सूचकांक को संदर्भित करने का प्रयास करने से पहले $ # {$ array [3]} मुख्य सरणी की सबस्क्रिप्टिंग को ठीक से हल करता है।
  • अकेले इस्तेमाल किया गया

    $ # {$ array [3]} = 9;

    autovivified सरणी को $ सरणी [3] पर 9 की लंबाई निर्दिष्ट करता है।

  • संदेह होने पर, डाटा :: डम्पर का उपयोग करें:

    use Data::Dumper; 
    $#{$array[3]} = 5; 
    $#array  = 10; 
    print Dumper(\@array, $array), "\n"; 
    
5

आप अनिवार्य रूप से विहित जवाब अपने आप को दे दी है। आप पिछले सूचकांक की स्थापना करके एक सरणी छोटा:

$#Array = 42 

सरणी में पिछले सूचकांक को दर्शाने के लिए $ # फू अंकन बिल्कुल नहीं पदावनत है। इसी तरह, इसे आवंटित करने के लिए या तो बहिष्कृत नहीं किया जाएगा। Perldata दस्तावेज़ीकरण का उद्धरण:

एक सरणी की लंबाई एक स्केलर मान है। सीएसएच में $ # दिन का मूल्यांकन करके आपको सरणी @days की लंबाई मिल सकती है। हालांकि, यह सरणी की लंबाई नहीं है; यह अंतिम तत्व की सबस्क्रिप्ट है, जो अलग-अलग मान है क्योंकि आमतौर पर 0 वां तत्व होता है। $ # दिनों को असाइन करने से वास्तव में सरणी की लंबाई बदल जाती है। एक सरणी छोटा करना इस तरह से हस्तक्षेप मूल्यों को नष्ट कर देता है। पहले से छोटा एक सरणी को लम्बाई करना उन मानों को पुनर्प्राप्त नहीं करता है जो तत्वों में थे। (यह पर्ल 4 में ऐसा करने के लिए इस्तेमाल किया है, लेकिन हम यह सुनिश्चित करें विनाशकर्ता जब उम्मीद कहा जाता था बनाने को यह तोड़ने के लिए किया था।)

7

$# चर अमान्य हो चुकी है, लेकिन $#array सुविधा नहीं है।

$#array सिंटैक्स का उपयोग मनमाने ढंग से अभिव्यक्ति पर करने के लिए करें जो एक सरणी संदर्भ उत्पन्न करता है, $#{ EXPR } करें।

अमूल्य देखें: http://perlmonks.org/?node=References+quick+reference

0

वहाँ प्रश्न की व्याख्या के दो तरीके हैं।

  • सरणी की लंबाई को कैसे कम करें?
  • कैसे सरणी द्वारा खपत स्मृति की मात्रा कम करने के लिए?

जवाब में से अधिकांश अब तक पूर्व पर ध्यान केंद्रित। मेरे विचार में, इसका सबसे अच्छा जवाब splice फ़ंक्शन है। ,

splice @array, -10; 

हालांकि क्योंकि कैसे पर्ल सरणियों के लिए स्मृति का प्रबंधन, एक ही रास्ता सुनिश्चित करना है कि एक सरणी कम स्मृति लेता है एक नई सरणी में कॉपी करना है (और: उदाहरण के लिए, अंत से 10 तत्वों को दूर करने के पुरानी सरणी की स्मृति को पुनः दावा किया जाना चाहिए)। इसके लिए, मैं स्लाइस ऑपरेशन का उपयोग करने के बारे में सोचने के लिए सोचूंगा।

original: length 500 => size 2104 
    pound: length 490 => size 2208 
    splice: length 490 => size 2104 
    delete: length 490 => size 2104 
    slice: length 490 => size 2064 

आप देख सकते हैं कि केवल टुकड़ा आपरेशन (एक में कॉपी किया:

@new = @old[ 0 .. $#old - 10 ] 

यहाँ (2104 बाइट्स का प्रयोग करके) एक 500 तत्व सरणी के लिए अलग-अलग दृष्टिकोण की तुलना की गई: उदाहरण के लिए, 10 तत्वों को दूर करने के नई सरणी) मूल की तुलना में एक छोटा आकार है।

यहाँ कोड मैं इस विश्लेषण के लिए इस्तेमाल किया है:

use strict; 
use warnings; 
use 5.010; 
use Devel::Size qw/size/; 

my @original = (1 .. 500); 
show('original', \@original); 

my @pound = @original; 
$#pound = $#pound - 10; 
show('pound', \@pound); 

my @splice = @original; 
splice(@splice,-10); 
show('splice', \@splice); 

my @delete = @original; 
delete @delete[ -10 .. -1 ]; 
show('delete', \@delete); 

my @slice = @original[0 .. $#original - 10]; 
show('slice', \@slice); 

sub show { 
    my ($name, $ref) = @_; 
    printf("%10s: length %4d => size %d\n", $name, scalar @$ref, size($ref)); 
} 
संबंधित मुद्दे