PHP में गोल्फिंग के लिए टिप्स


37

PHP में गोल्फिंग के लिए आपके पास क्या सामान्य सुझाव हैं? मैं उन विचारों की तलाश कर रहा हूं जो सामान्य रूप से PHP में कोड की समस्याओं को लागू कर सकते हैं जो कम से कम PHP के लिए कुछ विशिष्ट हैं (उदाहरण के लिए "टिप्पणियां हटाएं" एक उत्तर नहीं है)। कृपया प्रति उत्तर एक टिप पोस्ट करें।


रुको, क्या मैं इसे सही कर रहा हूं? ... वैसे भी, मैं वास्तव में इस बारे में उत्सुक हूं। PHP का उपयोग कई लोग और गोल्फर करते हैं, लेकिन मुझे लगभग नहीं पता है कि PHP कोड को कैसे गोल किया जाए।
जूनपीएन 20'11

लघु टैग का उपयोग करें <??> यह कुछ बाइट्स बचा सकता है।
Mob

जवाबों:


22

समझें कि PHP के भाषा निर्माण के साथ चर और व्हाट्सएप कैसे इंटरैक्ट करते हैं।

मेरे (सामान्य रूप से कम) समय गोल्फिंग में, मैंने पाया है कि PHP की भाषा कंस्ट्रक्शन और व्हॉट्सएप के साथ बातचीत करते समय कम-से-सहज तरीके से व्यवहार करती है (जैसे, प्रतिध्वनि, वापसी, के लिए, आदि)।

echo$v;, उदाहरण के लिए, पूरी तरह से मान्य हैं, जैसा कि return$v;और इसी तरह के अन्य निर्माण हैं। व्हॉट्सएप में इन छोटी कटौती से लंबाई में एक महत्वपूर्ण संचयी कमी हो सकती है।

हालांकि, ध्यान रखें कि भाषा के निर्माण से पहले चर के बाद निम्न उदाहरण में एक स्थान की आवश्यकता होती है:

foreach($a AS$b){}

क्योंकि ASएक भाषा का निर्माण होता है, चर से पहले एक स्थान की आवश्यकता नहीं होती है $b, लेकिन अगर किसी को इससे पहले अंतरिक्ष को छोड़ना पड़ता है , जिसके परिणामस्वरूप $aAS, यह एक चर नाम के रूप में पार्स किया जाएगा और एक सिंटैक्स त्रुटि की ओर ले जाएगा।


3
foreach($a[1]as$b)कोई सफेद जगह की जरूरत है। यह भाषा निर्माण और चर के बारे में नहीं है, बल्कि विभिन्न शब्दों के शब्द-वर्णों के बीच रिक्त स्थान के बारे में है।
टाइटस

1
एक अन्य उदाहरण जहां आपको व्हाट्सएप की आवश्यकता है, वह स्ट्रिंग समवर्ती में है। उदाहरण के लिए, echo $a+5." text"काम नहीं करेगा क्योंकि PHP सोचता है कि के .लिए एक दशमलव बिंदु है 5। इसे काम करने के लिए, आपको इस तरह एक स्थान जोड़ना होगा:echo $a+5 ." text"
Business Cat

@BasicSunset इस कथन को लिखा जा सकता है echo$a+5," text";echoनिर्माण आप एक से अधिक पैरामीटर पारित करने के लिए अनुमति देता है। जहां लिखना होगा echo"result: ".($a+5)."!";, आप लिख सकते हैं echo"result: ",$a+5,"!";। वास्तव में, एक से कई मापदंडों को पारित करना echoएक माइक्रो-ऑप्टिमाइज़ेशन है, क्योंकि कोड एक छोटा सा तेज़ी से चलेगा (चूंकि आप आउटपुट को संक्षिप्त नहीं करते हैं, लेकिन इसे अलग से भेजें)। सबसे तेज़ कोड को लिखने के बारे में चुनौतियों के लिए, यह छोटे छोटे छोटे बिट की मदद कर सकता है।
इस्माइल मिगुएल

@IsmaelMiguel इसके साथ काम करता है echo, लेकिन इसके साथ नहीं print(जिसकी आपको आवश्यकता है अगर आप इसे एक अभिव्यक्ति के अंदर रखते हैं: echoएक शुद्ध निर्माण है जिसमें कोई रिटर्न वैल्यू नहीं है, जबकि यह एक फ़ंक्शन के रूप में कार्य print कर सकता है : इसके लिए कोई कोष्ठक की आवश्यकता नहीं है, लेकिन यह हमेशा रिटर्न करता है int(1)
टाइटन

@ टिट्स के बारे में मैंने कुछ नहीं कहा print
इस्माइल मिगुएल

22

तार का उपयोग बुद्धिमानी से करें।

यह उत्तर दोतरफा है। पहला भाग यह है कि स्ट्रिंग्स की घोषणा करते समय, आप अंतरिक्ष को बचाने के लिए PHP के अज्ञात स्थिरांक के स्ट्रिंग्स में अंतर्निहित रूपांतरण का उपयोग कर सकते हैं, जैसे:

@$s=string;

यह @उत्पन्न होने वाली चेतावनियों को ओवरराइड करने के लिए आवश्यक है। कुल मिलाकर, आप एक-चरित्र में कमी के साथ समाप्त होते हैं।

वह यह है कि कभी-कभी, यह अक्सर उपयोग किए जाने वाले फ़ंक्शन के नाम के लिए एक चर सेट करने के लिए प्रभावी हो सकता है। आम तौर पर, आपके पास हो सकता है:

preg_match(..);preg_match(..);

लेकिन जब गोल्फ, यह आसानी से छोटा किया जा सकता है:

@$p=preg_match;$p(..);$p(..);

"Preg_match" के केवल दो उदाहरणों के साथ, आप केवल एक ही चरित्र को बचा रहे हैं, लेकिन जितना अधिक आप किसी फ़ंक्शन का उपयोग करते हैं, उतना ही अधिक स्थान आप बचाएंगे।


10
@ कोडगुल्फ़ में ज़रूरत नहीं है; नोटिस और चेतावनी (सहित E_DEPRECATED) स्वीकार्य हैं
टाइटस

3
@Titus लेकिन PHP में, चेतावनी मानक फ़ाइल आउटपुट के लिए आउटपुट होगी, इसलिए उनकी आवश्यकता है।
brianush1

1
@ मुझे विश्वास है कि आप उन्हें php.iniफाइल में दबा सकते हैं
स्टेन स्ट्रम

12

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

<?php defined('BASE_PATH')||die('not allowed');

या सामान्य कार्यों में

$value && run_this();

के बजाय

if($value) { run_this(); }

यह JS में भी काम करता है
гвгений Новиков

8

लघु सरणी सिंटैक्स का उपयोग करें

PHP 5.4 के बाद से, array()फ़ंक्शन के बजाय वर्ग ब्रैकेट (जावास्क्रिप्ट की तरह) का उपयोग करके ऐरे को घोषित किया जा सकता है:

$arr=['foo','bar','baz'];
// instead of
$arr=array('foo','bar','baz');

यह पांच बाइट्स बचाएगा।


लेकिन यह बाइट खर्च कर सकता है यदि आपके पास एक सहयोगी सरणी में "छेद" है:

$arr=array(,1,,3,,5);
// is one byte shorter than
$arr=[1=>1,3=>3,5=>5];

यदि आप "खाली" मानों के साथ छेद भर सकते हैं तो नुकसान थोड़ी देर बाद आता है:

$arr=[0,1,0,3,0,5,0,7,0,9,10,11];
// costs two byte more than
$arr=array(,1,,3,,5,,7,,9,,11);

2
PHP 7.1 ने लघु सूची असाइनमेंट भी पेश किया [,$a,$b,$c]=$argv;:।
टाइटस

7

$ {0}, $ {1}, $ {2}, का उपयोग करें ... के बजाय $ a [0], $ a [1], $ a [2], ...

जब तक आप एक सरणी हेरफेर नहीं कर रहे हैं, तब तक एक सरणी इंडेक्स के अधिकांश संदर्भों को $a[$i]बस के साथ बदला जा सकता है $$i। यह तब भी सच है जब सूचकांक एक पूर्णांक है, क्योंकि पूर्णांक PHP में वैध चर नाम हैं (हालांकि शाब्दिकों को कोष्ठक, जैसे की आवश्यकता होगी ${0})।

Rabonowitz Wagon spigot के निम्नलिखित कार्यान्वयन पर विचार करें:

3.<?for(;$g?$d=0|($a[$g]=$d*$g--/2+($a[$g]?:2)%$g*1e4)/$g--:238<<printf($e?'%04d':'',$e+$d/$g=1e4)^$e=$d%$g;);

इसे 6 बाइट्स द्वारा सुधारा जा सकता है, बस इसके बजाय दोनों एरे संदर्भों $a[$g]को बदलकर $$g:

3.<?for(;$g?$d=0|($$g=$d*$g--/2+($$g?:2)%$g*1e4)/$g--:238<<printf($e?'%04d':'',$e+$d/$g=1e4)^$e=$d%$g;);

1
मैंने उस के साथ केवल 3 बाइट्स बचाए: शोकेस
टाइटस

6

लाइब्रेरी कार्यों का एक बड़ा सबसेट सीखें

PHP का पुस्तकालय बहुत बड़ा है और सुविधाजनक कार्यों के एक टन प्रदान करता है जो विभिन्न कार्यों को बहुत छोटा कर सकता है। आप हर बार जब आप कुछ करने की कोशिश करते हैं, तो आप खोज सकते हैं, लेकिन समय बर्बाद करने से परे आपको ऐसा कुछ नहीं मिल सकता है जो आपकी विशेष खोज से मेल खाता हो। सबसे अच्छा तरीका सिर्फ पुस्तकालय से परिचित होना है और फ़ंक्शन नामों को याद रखना और वे क्या करते हैं।


6
यह एक बहुत याद है, विशेष रूप से कार्यों की एक पूरी बहुत असंगत नाम दिया ;-)
जॉय

@ जॉय सहमत। जावा लाइब्रेरी को याद करने के लिए अकिन, सिवाय इसके कि यह अधिक क्रियात्मक होने के बाद यकीनन कम उपयोगी होगा।
मैथ्यू पढ़ें

3
मुझे लगता है कि अब तक जो भी चुनौतियाँ आई हैं, उनके लिए सबसे महत्वपूर्ण कार्य स्ट्रिंग हेरफेर और सरणी हेरफेर फ़ंक्शन हैं। उन का रचनात्मक उपयोग वास्तव में कोड में कटौती कर सकता है।
मिग्मारू

6

स्ट्रिंग्स के अंदर चल रहे कार्य।

इसे इस्तेमाल करे:

$a='strlen';
echo "This text has {$a('15')} chars";

या यह प्रयास करें:

//only php>=5.3
$if=function($c,$t,$f){return$c?$t:$f;};
echo <<<HEREDOCS
    Heredocs can{$if(true,' be','not be')} used too and can{$if(<<<BE
{$if(true,1,0)}
BE
,'','not')} be nested
HEREDOCS;
//Expected output: Heredocs can be used too and can be nested

यह केवल स्ट्रिंग्स का उपयोग करके काम करता है ""और वंशानुगत (DON'T अब भ्रम के साथ भ्रम पैदा करता है)।

नेस्टेड फ़ंक्शंस का उपयोग करना नेस्टेड हेरेडोक्स के अंदर ही संभव है (या आप पार्स त्रुटियों में चलेंगे)!


you will run into parse errorsमैं इसे खुद नहीं पढ़ सकता? पेसकी ज़ेंड इंजन इसे एक साथ कैसे डालता है
स्टेन स्ट्रम

अगली बार जब मैं "PHP एक अच्छी प्रोग्रामिंग भाषा" तर्क में हूँ, तो मैं इसे काउंटर-पॉइंट के रूप में उपयोग करने जा रहा हूँ। वाह।
प्रिमो

@primo क्या यह बुरा है? : ओ
इस्माइल मिगुएल

5

टाइपकास्ट के साथ मज़ा

  • !!$fooकिसी भी सत्य मान को true(या 1आउटपुट में), मिथ्या मान (0, खाली स्ट्रिंग, खाली सरणी) में बदल देगा false(या खाली आउटपुट)
    यह कोड गोल्फ में शायद ही कभी आवश्यक होगा, ज्यादातर मामलों में जहां आपको बूलियन की आवश्यकता होती है, वहां एक निहित कलाकारों वैसे भी।

  • (int)$fooके रूप में $foo|0या लिखा जा सकता है foo^0, लेकिन कोष्ठक की आवश्यकता हो सकती है।
    बूलियन्स और स्ट्रिंग्स के लिए, $foo*1या +$fooइंट कास्ट करने के लिए इस्तेमाल किया जा सकता है।

  • अधिकांश अन्य भाषाओं के विपरीत, PHP अंकों के रूप में संख्यात्मक मूल्यों के साथ तार को संभालती है। इसलिए यदि आपके पास कोई स्ट्रिंग है जिसमें एक संख्या है जिसे आपको गणना करना है, तो बस गणना करें।
  • दूसरा तरीका काम नहीं करता है: किसी चर में किसी संख्या को गुणा करने के लिए 10, आप एक शून्य जोड़ सकते हैं: *10-> .0। लेकिन इस मामले में, PHP डॉट को दशमलव बिंदु के रूप में ले जाएगा और शिकायत करेगा। (यदि आप एक स्ट्रिंग में शून्य की एक चर राशि है तो यह अलग है।)
  • किसी सरणी को स्ट्रिंग में बदलने के लिए, joinइसके बजाय का उपयोग करें implode
    यदि आपको एक सीमांकक की आवश्यकता नहीं है, तो इसका उपयोग न करें: join($a)जैसा कि करता हैjoin('',$a)
  • इंक्रीमेंटिंग स्ट्रिंग्स: सबसे अद्भुत फीचर imo है जो $s=a;$s++;पैदा करता है $s=b;। यह अपरकेस और लोअरकेस वर्णों के साथ काम करता है। $s=Z;$s++;में परिणाम $s=AA;
    यह मिश्रित मामले के साथ भी काम करता है: aZटू bA, A1टू A2, A9टू B0और z99Zटू aa00A
    कमी स्ट्रिंग्स पर काम नहीं करती है। (और यह चालू नहीं है NULL)।
    PHP 3 में वापस, $n="001";$n++;निर्मित $n="002";। मैं थोड़ा दुखी हूं कि उन्होंने इसे हटा दिया।

जो भी आप गोल्फ: हमेशा ऑपरेटर पूर्वता तालिका हाथ में है।


4

शॉर्टटैग का प्रयोग करें

सामान्य कोड में, इसका उपयोग करना अच्छा है <?phpऔर ?>। हालाँकि, यह सामान्य कोड नहीं है - आप एक कोड गोल्फ कोड लिख रहे हैं। <?phpलिखने के बजाय <?<?php echoलिखने के बजाय <?=?>अंत में टाइप न करें - यह पूरी तरह से वैकल्पिक है। यदि आपको ?>किसी कारण की आवश्यकता है (उदाहरण के लिए पाठ को आउटपुट करने के लिए, और यह किसी भी तरह से छोटा है, या कुछ और है, तो इससे पहले अर्धविराम न लगाएं - इसकी आवश्यकता नहीं है, जैसा ?>कि अर्धविराम का अर्थ है।

गलत (निश्चित रूप से बहुत लंबा):

<?php echo ucfirst(trim(fgets(STDIN)));?>s!

सही बात:

<?=ucfirst(trim(fgets(STDIN)))?>s!

-rध्वज के साथ ( जो मुफ़्त आता है ), आप किसी भी टैग को बिल्कुल भी नहीं हटाते हैं (और आपको कोई भी उपयोग करने की अनुमति नहीं है)।
टाइटस

4

तारों के माध्यम से पाशन

26 बाइट्स के साथ या 24 से 18 के साथ किया जा सकता है:

foreach(str_split($s)as$c)  # A) 26 - general
for($p=0;a&$c=$s[$p++];)    # B) 24 - general
for($p=0;$c=$s[$p++];)      # C) 22 - if $s has no `0` character
for(;a&$c=$s[$p++];)        # D) 20 - if $p is already NULL or 0 (does NOT work for false)
for(;$c=$s[$p++];)          # E) 18 - both C and D

for(;$o=ord($s[$p++]);)     # F) 23 - work on ASCII codes, if $s has no NULL byte and D
for(;~$c=$s[$p++];)         # G) 19 - if $s has no chr(207) and D

$a&$bएक बिटवाइज़ और (ascii का कोड) में पात्रों पर करता है $aऔर $b
और एक स्ट्रिंग के छोटे रूप में एक ही लंबाई है में परिणाम $aऔर $b


क्या आप इस प्रश्न के खिलाफ ord($s[$p++])वैकल्पिक के रूप में जोड़ सकते हैं codegolf.stackexchange.com/questions/116933/…for(;$s+=ord($argv[++$i])%32?:die($s==100););for(;$c=$argv[++$i];)$s+=ord($c)%32;echo$s==100;
Jörg Hülsermann

कृपया ~उन मामलों के लिए जोड़ें जिन पर आप केवल अंकों के साथ काम कर रहे हैं
Jörg Hülsermann

ध्यान दें कि PHP 7.2 ~$cदृष्टिकोण के लिए चेतावनी देता है ।
टाइटस

4

टर्नरी ऑपरेटरों का उपयोग करें

if(a==2){some code;}else{some other code;}

इसे संक्षिप्त किया जा सकता है:

(a==2?some code:some other code);

छोटा, हुह?


"सशर्त शॉर्टहैंड"? बेहतर इसका असली नाम बताएं, ताकि अधिक विवरणों में रुचि रखने वाले इसे प्रलेखन में पा सकें: टर्नरी ऑपरेटर
५३ पर manatwork

3
सवाल उन टिप्स के लिए पूछता है जो PHP के लिए कुछ विशिष्ट हैं। यह सभी भाषाओं की युक्तियों में शामिल है ।
पीटर टेलर

3
यदि आप इसे घोंसले में रखते हैं तो टर्नरी ऑपरेटर का PHP में अजीब व्यवहार होता है। a?aa:ab?aba:abb:bमूल्यांकन (a?aa:ab)?(aba):(abb)या ऐसा कुछ।
टाइटस

1
और PHP 5.3 से शुरू होकर, आप दूसरे ऑपरेटर को छोड़ सकते हैं: $a?:$bजैसा है वैसा ही है $a?$a:$b
टाइटस

1
@ कुछ ||PHP में बूलियन के लिए जाती है।
तैतस

3

किसी अन्य नाम से ... फ़ंक्शन उपनाम

उपयोग ...

  • join के बजाय implode
  • chopके बजाय rtrim( chopपर्ल में अलग है!)
  • die के बजाय exit
  • fputs के बजाय fwrite
  • is_intके बजाय is_integerयाis_long
  • is_realके बजाय is_floatयाis_double
  • key_exists के बजाय array_key_exists
  • mysql के बजाय mysql_db_query

... सबसे महत्वपूर्ण उपनाम का नाम। अधिक के लिए http://php.net/aliases पर एक नज़र डालें ।


ओह ... और क्या आप जानते हैं कि dieमापदंडों के साथ और बिना काम करता है? die(1)त्रुटि कोड के साथ कार्यक्रम से बाहर निकल जाएगा 1(इस पर पूरी तरह से निश्चित नहीं; परीक्षण की आवश्यकता है); dieकोड के साथ बाहर निकल जाएगा 0, और मुद्रण die("Hello")के 0बाद कोड के साथ बाहर निकल जाएगा Hello
टाइटस

3

सहयोगी सरणियों को +ऑपरेटर के साथ विलय किया जा सकता है ।

के बजाय:

$merged = array_merge($a, $b);

उपयोग:

$merged = $a + $b;

ध्यान दें कि +ऑपरेटर अनुक्रमित सरणियों के साथ भी काम करता है, लेकिन संभवतः वह नहीं करता है जो आप चाहते हैं।


वास्तव में, अक्सर एक अच्छा प्रतिस्थापन, हालांकि बिल्कुल वैसा ही नहीं: pastebin.com/seYeaP38
मैनटवर्क

आह, यह खतरा है, मैं मूल रूप से शीर्षक "साहचर्य सरणियों ..." था और फिर इसे हटा दिया। मैं स्पष्ट करूँगा, धन्यवाद।
एलेक्स हॉवान्स्की

संख्यात्मक सरणियों का उपयोग करके भी विलय किया जा सकता है +, जब तक कि सूचकांक अलग-अलग हैं। यदि वे नहीं हैं, तो पहली सरणी के मान दूसरे वाले से अलग हो जाएंगे (जैसे array_merge)। अंतर: +अनुक्रमित अनुक्रमित नहीं करता है।
टाइटस

3

array_flip बनाम array_search

उपयोग

array_flip($array)[$value]

के बजाय

array_search($value,$array)

1 बाइट को सरणियों में सहेजना जहां प्रत्येक मूल्य की घटना अद्वितीय है


3

चर चर पर कुछ रोचक तथ्य

मुझे सिर्फ उन्हें साझा करना था (इससे पहले कि मैंने सत्यापित किया कि उनमें से कम से कम एक गोल्फिंग में मदद करता है):

  • अक्षरों का उपयोग करें: $x=a;$$x=1;$x++;$$x=2;echo"$a,$b";प्रिंट 1,2
    लेकिन अन्य अंकगणितीय ऑपरेशन अक्षरों के साथ काम नहीं करते हैं।
  • जैसा कि पहले उल्लेख किया गया है , आप चर नामों के रूप में शुद्ध संख्याओं का उपयोग कर सकते हैं:
    $a=1;$$a=5;$a++;$$a=4;${++$a}=3;echo${1},${2},${3};प्रिंट 543
  • आप न केवल [0-9a-zA-Z_]चर नामों के लिए उपयोग कर सकते हैं , लेकिन हर स्ट्रिंग:
    $x="Hello!";$$x="Goodbye.";echo${"Hello!"};प्रिंट Goodbye.
  • लेकिन: सब कुछ लेकिन [a-zA-Z_][a-zA-Z_0-9]*चर नामों के रूप में शाब्दिक उपयोग के लिए ब्रेसिज़ की आवश्यकता होती है।
  • कोई चर परिभाषित नहीं करता है, $$x=1सेट करता है ${NULL}, जो कि जैसा है ${false}और है ${""}
  • $a=1;$$a=5;केवल सेट ही नहीं करता ${1}, बल्कि करता भी है ${true}

  • एक और, एक अजीब एक Ive अब तक मिला: कोशिश करो $a=[];$$a=3;echo${[]};। हाँ, यह प्रिंट करता है 3!

इनमें से अधिकांश का कारण: चर नामों का मूल्यांकन हमेशा तार के लिए किया जाता है।
(धन्यवाद @Christoph को इंगित करने के लिए।)
इसलिए, जब भी आपको printया echoअभिव्यक्ति पर जो कुछ भी मिलता है , वह वही है जो आपको चर नाम से मिलता है।


1
परिवर्तनीय नाम स्ट्रिंग में परिवर्तित हो जाते हैं जो आपकी सूची के अंतिम तीन बिंदुओं को बताते हैं। []में कनवर्ट करता है Array: ${[]} = 5;echo $Array;प्रिंट 5। मुझे पूरा यकीन है कि आप जानते हैं कि लेकिन यह सभी के लिए स्पष्ट नहीं हो सकता है :)
क्रिस्टोफ़

@ जेफ़ मैंने टाइपो को ठीक किया। ध्यान देने के लिए धन्यवाद।
टाइटस

2


यदि लाइन को आउटपुट की आवश्यकता होती है तो लाइन ब्रेक, भौतिक लाइन ब्रेक (1 बाइट) का उपयोग करें। इसके बजाय "\n"
आपको सिंगल और डबल कोट्स के बीच चयन करने का संभावित लाभ मिलता है।


2

जहाँ संभव हो, उद्धरण से बचें

PHP शब्दशः अज्ञात शब्दों को शाब्दिक तार के लिए प्रस्तुत करता है।

$foo=foo;के रूप में ही है $foo='foo';(यह मानते हुए कि fooन तो एक महत्वपूर्ण शब्द या एक परिभाषित स्थिर है): $foo=echo;काम नहीं करता है।

लेकिन: $p=str_pad;करता है; और का $p(ab,3,c)मूल्यांकन करता है abc

उद्धरण के बिना स्ट्रिंग शाब्दिक का उपयोग करने के लिए एक नोटिस निकलेगा Use of undefined constant; लेकिन यदि आप error_reporting(CLI पैरामीटर -n) के लिए डिफ़ॉल्ट मान का उपयोग नहीं करते हैं तो यह दिखाएगा ।


मैंने अभी देखा: यह उत्तर कोडगॉल्फ.स्टैकएक्सचेंज . com /a/ 2916 / 55735 का कुछ हद तक विस्तारित / अद्यतन डुप्लिकेट है ।
टाइटस

ध्यान दें: 7.2 से पहले PHP ने नोटिस प्राप्त किया (जिसे आप -nध्वज के साथ खोल सकते हैं ); 7.2 पैदावार चेतावनी; बाद के संस्करण त्रुटियाँ फेंक देंगे!
टाइटस

2

PHP 7.4 में एरो फ़ंक्शंस

PHP 7.4 अब RC2 संस्करण पर है और उम्मीद है कि लगभग 2 महीने में रिलीज़ हो जाएगी। नई सुविधाओं की सूची यहां है (यह पेज वास्तव में अपडेट किया जा सकता है जब 7.4 जारी किया जाता है)। 7.4 में, अंत में PHP को एरो फ़ंक्शंस मिले हैं, इसलिए न केवल फ़ंक्शन उत्तर अब छोटे हो सकते हैं, बल्कि अन्य फ़ंक्शंस के लिए पासिंग भी बहुत कम हो सकती है। कुछ उदाहरण निम्नलिखित हैं:

वापसी इनपुट + 1:

बेनामी फ़ंक्शन (बंद) - 25 बाइट्स - इसे ऑनलाइन आज़माएं!

function($n){return$n+1;}

एरो फ़ंक्शन - 12 बाइट्स - इसे ऑनलाइन आज़माएं!

fn($n)=>$n+1

दूसरे इनपुट (इंट) द्वारा पहले इनपुट (ints के सरणी) के गुणा आइटम:

अनाम फ़ंक्शन (बंद) - 72 बाइट्स - इसे ऑनलाइन आज़माएं!

function($a,$n){return array_map(function($b)use($n){return$b*$n;},$a);}

एरो फ़ंक्शन - 38 बाइट्स - इसे ऑनलाइन आज़माएं!

fn($a,$n)=>array_map(fn($b)=>$b*$n,$a)

क्या आपने देखा कि $nएक use $nबयान के बिना आंतरिक कार्य में सुलभ है ? हाँ, जो कि तीर फंक्शन की विशेषताओं में से एक है।


एक साइड नोट के रूप में, मुझे पुनरावर्ती रूप से काम करने के लिए तीर फ़ंक्शन नहीं मिल सके (स्वयं के अंदर एक ही तीर फ़ंक्शन को कॉल करें), क्योंकि हम उन्हें एक नाम नहीं दे सकते हैं और उन्हें एक चर में बंद होने के रूप में संग्रहीत कर सकते हैं जैसे $fकि $fखुद को सुलभ नहीं बनाता है (उदास) )। तो यह उदाहरण काम नहीं करता है और $fपहली पंक्ति में उपयोग करने से घातक त्रुटि होती है:

$f=fn($n)=>$n?$f($n-1):0;
$f(5); // Causes error: "PHP Notice: Undefined variable: f" + "PHP Fatal error: Uncaught Error: Function name must be a string"

लेकिन एक एरो फंक्शन को कॉल करना एक अलग एरो फंक्शन काम करता है:

$f1=fn($n)=>$n+1;
$f2=fn($n)=>$f1($n-1);
$f1(2) // Returns 3
$f2(2) // Returns 2

अगर $f=fn($n)=>$n?$f($n-1):0;आप के बजाय क्या करते हो $f=$F=fn($n)=>$n?$F($n-1):0;? क्या इससे काम हो जायेगा? और फिर आप $(5)हमेशा की तरह बुलाते हैं ।
इस्माइल मिगुएल

@IsmaelMiguel अभी भी वही त्रुटि फेंक रहा है। आप वास्तव में tio.run पर कोशिश कर सकते हैं # php खुद के रूप में कुछ समय पहले डेनिस ने अपने PHP को 7.4 RC2 में अपडेट किया है।
Night2

यह काम करने के लिए नहीं मिल सकता है। लगता है कि केवल पहले से परिभाषित चर उपलब्ध हैं।
इस्माइल मिगुएल


1

प्रत्यक्ष रूप से डीरेंस एरे कार्यों से लौटे।

इसके बजाय, उदाहरण:

$a = foo();
echo $a[$n];

तुम कर सकते हो:

echo foo()[$n];

यह तरीकों के साथ भी काम करता है:

echo $obj->foo()[$n];

तुम भी सीधे सरणी की घोषणा कर सकते हैं:

echo [1, 2, 3, 4, 5][$n];

1

के end()बजाय का उपयोग करेंarray_pop()

end()समारोह बस सरणी के अंत करने के लिए आंतरिक पॉइंटर को चलाने नहीं है, यह भी पिछले मान देता है। ध्यान दें कि यह उस मूल्य को नहीं हटाता है, इसलिए यदि आपको परवाह नहीं है कि सरणी में बाद में क्या है, तो आप इसके बजाय इसका उपयोग कर सकते हैं array_pop()


1

डबल array_flip बनाम in_array बनाम array_unique

इस विशेष मामले में एक डबल array_flip 10 बाइट्स बचाता है

($f=array_flip)($k=$f($c)))सरणी में सभी दोहरे मानों को निकालें और मैंने इसे छोड़ दिया है $c=[],, |in_array($o,$c)और इसके array_keys($c)साथ प्रतिस्थापित करें$k

for([,$x,$y]=$argv;a&$o=$y[$i];$i++)
$x[$i]==$o?:$c[$x[$i]]=$o; # if char string 1 not equal char string 2 set key=char1 value=char2
echo strtr($x,($f=array_flip)($k=$f($c)))==$y # boolean replacement string 1 equal to string 2
    ?join($k)." ".join($c) # output for true cases
:0; #Output false cases

ऑनलाइन संस्करण

विरुद्ध

for($c=[],[,$x,$y]=$argv;a&$o=$y[$i];$i++)
  $x[$i]==$o|in_array($o,$c)?:$c[$x[$i]]=$o; # if char string 1 not equal char string 2 set key=char1 value=char2
echo strtr($x,$c)==$y # boolean replacement string 1 equal to string 2
  ?join(array_keys($c))." ".join($c) # output for true cases
  :0; #Output false cases

ऑनलाइन संस्करण

array_unique के खिलाफ यह 2 बाइट्स बचाता है

for([,$x,$y]=$argv;a&$o=$y[$i];$i++)
  $x[$i]==$o?:$c[$x[$i]]=$o; # if char string 1 not equal char string 2 set key=char1 value=char2
echo strtr($x,array_unique($c))==$y # boolean replacement string 1 equal to string 2
  ?join(array_keys($c))." ".join($c) # output for true cases
  :0; #Output false cases

ऑनलाइन संस्करण

इस कार्यक्रम में बग ढूंढने के बाद और डबल array_flip को बदलने के $x[$i]==$o?:$c[$x[$i]]=$oलिए ($p=$x[$i])==$o?:$k[$c[$p]=$o]=$pअधिक समय तक आवश्यक नहीं था


साहचर्य सुरक्षित array_unique। वाह!
टाइटस

@ टिट्स मैंने आपके सुझाव को जोड़ा है
Jörg Hülsermann

1

तारों को काटना

क्या आपने कभी
join("DELIMITER",str_split($s))(31 बाइट) या
preg_replace(".","DELIMITER",$s)(32 बाइट) का उपयोग किया है
?

उस के लिए बनाया गया है:

प्रयास करें chunk_split($s,1,"DELIMITER")(29 बाइट्स)।


यदि आप तीसरे पैरामीटर को छोड़ते हैं, chunk_splitतो उपयोग करेंगे \r\n; जो आपको 7 या 8 बाइट्स बचा सकता है।

लेकिन खबरदार: chunk_splitस्ट्रिंग को सीमांकक भी जोड़ता है,
इसलिए आपको वह नहीं मिल सकता है जो आप चाहते हैं।

(यदि आप चंक की लंबाई प्रदान नहीं करते हैं, तो यह 76 का उपयोग करेगा। कोड गोल्फ के लिए असामान्य है, लेकिन कौन जानता है।)


हो सकता है कि आपको strtrइस विचार से प्यार होने के साथ संयोजन में एक उदाहरण जोड़ना चाहिए ।
जोर्ग हल्सरमैन

1

unset () बनाम INF

एक मामले में एक सरणी में कम से कम के लिए खोज आप के बजाय का उपयोग कर सकते हैं

unset($var[$k]);

$var[$k]=INF;

3 बाइट बचाने के लिए


1

str_repeat

कुछ मामलों में आपके पास वर्णों का एक इनपुट होता है और आपको प्रत्येक वर्ण के लिए अधिक से अधिक शून्य इनपुट के साथ उन्हें दोहराया जाना चाहिए।

for(;--$z?:($c=$argn[$i++]).$z=$argn[$i++];)echo$c;

(52 बाइट्स) से छोटा है

for(;~$c=$argn[$i++];)echo str_repeat($c,$argn[$i++]);

या

for(;~$c=$argn[$i++];)echo str_pad($c,$argn[$i++],$c);

(54 बाइट्स प्रत्येक)

यह उदाहरण इनपुट के लिए कैसे काम करता है a1b2c1

$zसेट नहीं है (निहित NULL), इसलिए --$zकुछ नहीं करता है और झूठा है;

$c="a", $z="1"और $i=2-> $c.$z="a1"सत्य है -> आउटपुट"a"

--$z=0; इसलिए हम सेट $c="b", $z="2"(और $i=4) -> $c.$z="b2"सत्य है -> आउटपुट"ab"

--$z=1 -> आउटपुट "abb"

--$z=0; इसलिए हम सेट करते हैं $c="c"और $z=1 $c.$z="c1"सच्चा आउटपुट है"abbc"

--$z=0तो $c=""और $z=""-> $c.$z=""मिथ्या है -> पाश टूट जाता है


1

forछोरों का मेल

मान लें कि आपके पास निम्नलिखित फ़ॉर्म का कोड है:

for($pre1; $cond1; $post1) for($pre2; $cond2; $post2) $code;

इसे आम तौर पर निम्नलिखित रूप में फिर से रोल किया जा सकता है:

for($pre1; $cond2  $post2 || $cond1  $pre2  $post1; ) $code;

जहां एक सामान्य संयोजन ऑपरेटर का प्रतिनिधित्व करता है। यह आमतौर पर एक बाइट की गिनती में कमी के परिणामस्वरूप होता है, लेकिन संभवतः कुछ रचनात्मकता की आवश्यकता होगी। $cond2लिखने की आवश्यकता होगी ताकि यह पहली बार में विफल हो जाए। $post1पहली बार निष्पादित करने में भी विफल होना चाहिए, हालांकि पहले से रिफ्लेक्टर करना आसान हो सकता है ताकि $post1मौजूद न हो।

यदि आप तीन या अधिक नेस्टेड छोरों के साथ काम कर रहे हैं, तो आप पहले दो को भी जोड़ सकते हैं, और फिर दूसरे को जोड़ सकते हैं, और इसी तरह। मुझे लगता है कि आम तौर पर अंदर से बाहर की ओर गठबंधन करना आसान हो गया है।


एक उदाहरण के रूप में, एच-कालीन भग्न ( 97 बाइट्स ) के निम्नलिखित समाधान पर विचार करें :

for(;$i<$n=3**$argn;$i+=print"$s\n")for($s=H,$e=1;$e<$n;$e*=3)$s.=str_pad($i/$e%3&1?$s:'',$e).$s;

इसे निम्नलिखित तरीके से सुधारा जा सकता है:

for(;($i+=$e&&print"$s\n")<$n=3**$argn;)for($s=H,$e=1;$e<$n;$e*=3)$s.=str_pad($i/$e%3&1?$s:'',$e).$s;

$e&&printprintपहले पुनरावृत्ति को रोकता है , और वृद्धि भी नहीं करता है $i

और अंत में ( 93 बाइट्स ):

for(;$H>$e*=3or$e=($i+=$e&&print"$s\n")<${$s=H}=3**$argn;)$s.=str_pad($i/$e%3&1?$s:'',$e).$s;

$H>$e*=3 पहली बार विफल होगा क्योंकि दोनों चर अपरिभाषित हैं।


1

एक स्ट्रिंग में वर्णों को निकालना

join(explode(" ",$string));

की तुलना में 1 वर्ण बचाता है

str_replace(" ","",$string);

ध्यान दें कि यह सभी (गैर-रिक्त) तारों के लिए काम करता है, न कि केवल पात्रों के लिए।
कैलक्यूलेटरफल

@CalculatorFeline खाली तारों के लिए काम क्यों नहीं करना चाहिए? इसका कोई मतलब नहीं है या यह मामला है।
जोर्ग हल्सरमैन

खैर, पहले संस्करण के साथ काम नहीं करता है ""और यह वैसे भी बहुत उपयोगी नहीं है।
कैलकुलेटर

1
@ कैलाकेटरफेलिन और इस मामले के लिए एक शून्य बाइट समाधान बहुत बेहतर है। इस तरह से ऐसा करने का कोई मतलब नहीं है।
जॉर्ग हुल्सरमैन

3
आपका सम्मिलित उदाहरण याद आ रहा है )। और strtr($string,[" "=>""])उससे भी छोटा है।
टाइटस


1

की बूलियन ऑपरेटर का उपयोग करना बजाय strtoupper()औरstrtolower()

यदि आप वर्णमाला वर्णों से मिलकर तार के साथ विशेष रूप से काम कर रहे हैं, तो आप PHP के अंतर्निहित कार्यों की तुलना में कम कीस्ट्रोक्स के साथ अपरकेस या लोअरकेस में बदलने के लिए बूलियन ऑपरेटरों का उपयोग कर सकते हैं।

उदाहरण:

// Convert lowercase to uppercase
$s = "g";
echo strtoupper($s);  // Outputs 'G', uses 20 characters
echo~" "&$s;          // Outputs 'G', uses 12 characters

// Convert uppercase to lowercase
$s = "G";
echo strtolower($s);  // Outputs 'g', uses 20 characters
echo$s^" ";           // Outputs 'g', uses 11 characters

// Switch case of each character
$s = "Gg";
echo$s^"  ";          // Outputs 'gG', uses 12 characters

मनमानी लंबाई के तार के लिए चीजें थोड़ी पेचीदा होती हैं, लेकिन &और ^ऑपरेटर छोटी लंबाई के तार की लंबाई के परिणामस्वरूप परिणाम को छोटा कर देंगे। उदाहरण के लिए, यदि $Wकिसी इनपुट के रूप में कम से कम लंबे समय तक रिक्त स्थान है $s, तो ~$W&$sइसके बराबर है strtoupper($s), और $s|$W^$sइसके बराबर है strtolower($s)(जबकि $s|$Wस्वयं अतिरिक्त स्ट्रिंग के साथ एक स्ट्रिंग का उत्पादन करेगा जब तक कि $sऔर $Wसमान लंबाई के न हों)।


0

पदावनत कार्यों का उपयोग
आप अभिव्यक्ति, उपयोग पर अधिक से अधिक 5 बाइट्स बर्बाद कर के बिना PERL regex के बजाय POSIX उपयोग कर सकते हैं eregया eregiके बजाय preg_match, splitया splitiबजाय preg_split की।
splitभी explodeसबसे delimiters के लिए एक पर्याय के रूप में इस्तेमाल किया जा सकता है।

इन कार्यों को चिह्नित किया गया है और E_DEPRECATEDनोटिस फेंक देंगे , लेकिन (अब स्रोत नहीं मिल सकता है) मुझे लगता है कि मैंने पढ़ा है कि चेतावनी और नोटिस ठीक हैं।


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