2013-04-17 9 views
9

में "$ _ और 1" कैसे काम करता है मैं एक सूची फ़िल्टर करने के लिए grep फ़ंक्शन पर पढ़ रहा हूं। मैं निम्नलिखित कार्यक्रम में आया था।यह प्रतिलिपि

#!/usr/bin/perl 

use strict; 
use warnings; 

# initialize an array 
my @array = qw(3 4 5 6 7 8 9); 

# first syntax form: 
my @subArray = grep { $_ & 1 } @array; 

बयान my @subArray = grep { $_ & 1 } @array; रिटर्न @array में विषम संख्या। मुझे समझ में नहीं आया कि अभिव्यक्ति ($_ & 1) कैसे काम करती है। मैंने Google में खोज की लेकिन मुझे कोई उपयोगी लिंक नहीं मिला।

  • क्या यह किसी भी प्रकार का विशेष ऑपरेटर है?

  • क्या EXPR के कोई अन्य रूप हैं?

अग्रिम में धन्यवाद।

+0

जानकारी के लिए: यह एक बहुत ही साफ हैक ** कि उत्पादन कोड में प्रयोग नहीं करना चाहिए है ** जब तक केवल विषम तत्वों को खोजने का संचालन एक में एक प्रदर्शन टोंटी होने के लिए बेंचमार्क है अधिक पठनीय कार्यान्वयन। – DVK

+0

@ डीवीके एचएम, मेरी रुचि के लिए: क्या यह टिप उपयोग की जाती है? '$ _ || = $ val' – gaussblurinc

+0

@loldop -' || = 'ऑपरेटर पूरी तरह से उचित idiomatic पर्ल है, एक हैक नहीं। हालांकि, का उपयोग करते हुए '$ _' के रूप में एक आत्म documentedly नाम-variavle उपयोग करने के लिए बहुत बार खराब लिखा कोड का एक संकेत का विरोध किया है, जब तक एक बहुत ही कम' map'/'grep' ब्लॉक में प्रयोग किया जाता है। – DVK

उत्तर

10

$_ चर वर्तमान में परीक्षण किया मूल्य पकड़े, & द्विआधारी AND ऑपरेटर है, और 1 बस नंबर एक है वापस आ जाएगी है। यह अभिव्यक्ति तार्किक और एक दूसरे के साथ $_ और 1 दोनों के सभी बिट्स को जोड़ती है। इसलिए यदि मूल्य अजीब है और 0 मान भी है तो यह 1 लौटाता है।

उदाहरण के तौर पर, मान लें कि $ _ 123 है तो यह बाइनरी प्रतिनिधित्व 1111011 होगा। दशमलव संख्या 1 00000001 होगा, इसलिए द्वारा सभी बिट्स के संयोजन और आप

123 = 1111011 
    1 = 0000001 
     - AND - 
     0000001 = 1 

एक और उदाहरण 200 & 100

200 = 11001000 
100 = 01100100 
     - AND -- 
     01000000 = 64 
+0

दूसरे उदाहरण ('200 और 100') में, क्या उत्तर' 64' है या रूपांतरण का मेरा तरीका गलत है? –

+0

आप सही हैं, यह निश्चित रूप से 64 होना चाहिए। 128 मेरे हिस्से में एक त्रुटि थी। – tauli

1

$_ वर्तमान अभिव्यक्ति है। इस मामले में प्रत्येक सरणी तत्व।

& बाइनरी और ऑपरेटर है।

तो, संक्षेप में, grep किसी भी सरणी तत्व से मेल खाएगा जो एक विषम संख्या है।

$_ का उपयोग grepperldoc में किया गया है। & का अर्थ perldoc में भी है।

2
grep{ $_ & 1} 

अपने सरणी के प्रत्येक तत्व पर जाने और इसका मतलब है कि ग्रेप किसी भी तत्व को एक 1 के रूप में पिछले (LSB) सा है कि मिलान कर देंगे 1 साथ एक सा वार मैच होगा। के बाद से ही विषम संख्या एक 1 के रूप में LSB यह केवल विषम संख्या

& is the bitwise AND 
0

$_ एक चर ग्रेप समारोह द्वारा निर्धारित है मिलता है। अधिकांश पर्ल फ़ंक्शंस अन्यथा निर्दिष्ट नहीं होने पर $ _ में हेरफेर करते हैं। Grep @array के प्रत्येक तत्व के लिए परिभाषित अनाम उप (जो { $_ & 1 } है) को कॉल करता है और थोड़ा सा & बनाता है। यदि परिणाम एक वास्तविक मान है, तो यह परिणामस्वरूप सरणी में जोड़ा जाता है।

4

जैसा कि कई ने बताया है, & बिटवाई-ऑपरेटर है।इसका मतलब है कि दो नंबर है कि तुलना की जाती है बिट्स में बदल गया और तुलना की जाती है:

उदाहरण के लिए, 3 & 1 रिटर्न 1, जो ग्रेप अंदर सही का आकलन:

Num | Bits 
----+----- 
    3 | 1 1 
& 1 | 0 1 
----+----- 
    1 | 0 1 <- result of 'and'ing each bit column 

इसी तरह, 4 & 1 रिटर्न 0 है, जो झूठी:

Num | Bits 
----+------- 
    4 | 1 0 0 
& 1 | 0 0 1 
----+------- 
    0 | 0 0 0 <- all zeros because no column contains 1 & 1 

जिसके अनुसार, विषम संख्या फिल्टर करने के लिए एक वैकल्पिक तरीका है mod को 2 के साथ नंबर:

my @odd = grep { $_ % 2 } 1 .. 7; # 1, 3, 5, 7 
संबंधित मुद्दे