2009-08-02 13 views
11

मैं एक $input सरणी है कहो, जो कुछ इस तरह होती है:एक सरणी के भी क्रमांकित तत्वों को रखते हुए?

array 
    0 => string 'a' (length=1) 
    1 => string 'b' (length=1) 
    2 => string 'c' (length=1) 
    3 => string 'd' (length=1) 
    4 => string 'e' (length=1) 
    5 => string 'f' (length=1) 
    6 => string 'g' (length=1) 
    7 => string 'h' (length=1) 
    8 => string 'i' (length=1) 
    9 => string 'j' (length=1) 

मैं एक $output सरणी प्राप्त करना चाहते हैं, कि यह शामिल होगा:

array 
    0 => string 'a' (length=1) 
    1 => string 'c' (length=1) 
    2 => string 'e' (length=1) 
    3 => string 'g' (length=1) 
    4 => string 'i' (length=1) 

$output सरणी आधा मान हैं कि $input में थे; जिनके पास इनपुट में चाबियाँ भी थीं; पहले एक दूसरे से एक नहीं है, रखा जाता है, तीसरे में से एक है, और इसलिए एक ...

(नोट: कुंजी संरक्षित नहीं कर रहे हैं, केवल मान महत्वपूर्ण हैं)

मैं कैसे कर सकता है वो करें ? सरणी के दो मानों पर केवल एक को रखते हुए?


मैं पहले से ही कुछ विचारों की कोशिश की है, और पहले से ही एक जोड़े को अलग अलग समाधान है:

पहले विचार: इनपुट सरणी पर पुनरावृति, और आउटपुट सरणी के लिए दिलचस्प मूल्यों कॉपी:

$input = array('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j',); 
$output = array(); 

$nbr = count($input); 
for ($i = 0 ; $i < $nbr ; $i += 2) { 
    $output[] = $input[$i]; 
} 

var_dump(array_values($output)); 

दूसरा विचार: सरणी पर पुनरावृति, और unset मैं नहीं है क्या चाहते हैं रखने के लिए:

$input = array('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j',); 
$output = $input; 

$nbr = count($input); 
for ($i = 1 ; $i < $nbr ; $i += 2) { 
    unset($output[$i]); 
} 

var_dump(array_values($output)); 

तीसरा विचार:array_flip, range, array_diff_key के combinaison उपयोग करते हैं, ...:

$input = array('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j',); 
$output = array(); 

$keys_to_exclude = array_flip(range(1, count($input)-1, 2)); 
$output = array_diff_key($input, $keys_to_exclude); 

var_dump(array_values($output)); 

चौथा विचार: एक ही बात के बारे में, लेकिन array_intersect_key साथ:

$input = array('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j',); 
$output = array(); 

$keys_to_include = array_flip(range(0, count($input)-1, 2)); 
$output = array_intersect_key($input, $keys_to_include); 

var_dump(array_values($output)); 

कोई अन्य विचार? यहां तक ​​कि विशेष रूप से अगर यह थोड़ी हैकी या कुछ भी लगता है?

मेरा लक्ष्य सबसे कुशल और न ही सरल वाक्यविन्यास प्राप्त करना है; यह सिर्फ मजेदार है और क्योंकि मैं उत्सुक हूं, वास्तव में ^^

यदि शीर्षक सही शब्दों का उपयोग करने के लिए सही शब्दों का उपयोग नहीं कर रहा है, तो बताने में संकोच न करें; या यह:-)

+0

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

+0

संपादन के लिए धन्यवाद :-) ठीक है, वास्तव में, "मैं अपने आप से लूपिंग के दौरान ऐसा कैसे कर सकता हूं" एक सवाल है जो काम के कुछ दिनों पहले पॉप-अप था; एक सहयोगी और मैंने इसके बारे में सोचा ... और हमने अंततः "के लिए" समाधान (पहला मैंने दिया) का उपयोग किया: कम मजेदार, लेकिन समझने में आसान जब किसी को अपना कोड बनाए रखना होगा - और यह सबसे अधिक है हमारे काम में महत्वपूर्ण बात; लेकिन, यह अभी भी एक दिलचस्प सवाल था, और मैंने सोचा कि मुझे अपने विचारों के साथ अच्छी तरह से तैयार प्रश्न के लिए ^^ –

+0

+1 यहां कुछ मजाकिया/रोचक प्रस्ताव मिल सकते हैं – PatrikAkerstrand

उत्तर

15
<?php 
$x = range('a', 'f'); 

$x = array_map('array_shift', 
     array_chunk($x, 2) 
    ); 

var_dump($x); 

या एक और एक

<?php 
class ArrayEvenIterator extends ArrayIterator { 
    public function next() { 
     parent::next(); 
     return parent::next(); 
    } 
} 

$x = range('a', 'f'); 
$x = iterator_to_array(new ArrayEvenIterator($x), false); 

var_dump($x); 

या एक php 5.3 बंद के साथ

<?php 
$x = range('a', 'f'); 

$x = array_filter($x, function($e) use(&$c) { return 0===$c++%2; }); 

var_dump($x); 
+0

अच्छे लोग भी! धन्यवाद :-) बंद करने का उपयोग करने के बारे में नहीं सोचा था (मेरा दिमाग अभी तक PHP में उन लोगों के लिए उपयोग नहीं किया गया है, मुझे लगता है ^^ (और मैं जितना चाहूं PHP 5.3 का उपयोग नहीं कर सकता :-()) –

+1

बंद करने और 'iterator_to_array' के लिए +1 (जिसे मैं नहीं जानता था) के लिए +1। –

2

मान लिया जाये कि संख्यात्मक कुंजियों को संपादित:

foreach ($array as $key => $value) { 
    if ($key % 2 != 0) { 
     unset($array[$key]); 
    } 
} 

संपादित

यहाँ मेरी थोड़ा अधिक पागल समाधान जो बिना फिर से अनुक्रमण सूचकांक निरंतर रहता है चला जाता है ।; ओ)

foreach ($array as $key => $value) { 
    if (!($key%2)) { 
     $array[$key/2] = $value; 
    } 
} 
$array = array_slice($array, 0, ceil(count($array)/2)); 
+0

@ पास्कल (ओपी): मुझे यह मानना ​​है कि यह बहुत ही खतरनाक नहीं है आपके 'समाधान' से अलग, लेकिन मुझे लगता है कि आप पहले से ही लगभग सभी अड्डों को कवर करते हैं। अधिकांश सेन समाधानों को सिंटेक्टिक चीनी में काफी अलग होना चाहिए। :) – deceze

+0

यही वह है जो मैं सुझाव देने जा रहा था। यदि कुंजियां संख्यात्मक नहीं हैं तो आप संभवतः किसी फ़ंक्शन के माध्यम से सरणी चला सकते हैं और संख्यात्मक कुंजी वाले तत्वों की एक नई सरणी बना सकते हैं। प्रत्येक तत्व मूल सरणी से कुंजी/मान जोड़ी का सरणी होगा। मॉड्यूलस ऑपरेटर के बारे में अच्छी बात यह है कि इसका उपयोग सभी प्रकार के तत्वों को खोजने के लिए किया जा सकता है। प्रत्येक 5 वें तत्व को खोजने के लिए यदि ($ कुंजी% 5 == 0) इसका मतलब है कि 5 से विभाजित करें और शेष लौटें। 15 से 15 तत्वों की एक सूची 0, 5, 10, और 15 लौटाएगी जिनमें से प्रत्येक 5 से विभाजित होने पर शेष 0 लौटाएगी। उदाहरण के लिए 10/5 = 2 R0। –

+0

@deceze: हाँ, आप सही हैं, कोई "चमत्कार" और रखरखाव योग्य समाधान नहीं है ^^ लेकिन यह मजेदार था ;-) धन्यवाद, वैसे भी, मॉड्यूलस के बारे में नहीं सोचा था! –

0

ज़रूरी नहीं कि सबसे कारगर विधि है, लेकिन जब से तुम उल्लेख किया है कि अनिवार्य रूप से कोई आवश्यकता नहीं था ...

फ्लिप, फिल्टर, फिर वापस फ्लिप।

<?php 
    function even($var) 
    { 
     return(!($var & 1)); 
    } 

    $input = array('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j',); 
    $flipped = array_flip($input); 
    $filtered = array_filter($flipped, 'even'); 
    $output = array_flip($filtered); 
?> 
+1

यह इनपुट के आधार पर अप्रत्याशित/अनजान परिणाम उत्पन्न कर सकता है। जैसे $ इनपुट = सरणी ('ए', 'ए', 'बी'); -> $ आउटपुट == सरणी ('बी') – VolkerK

-2
function dropHalf($a){ 
    $f=0; 
    foreach($a as $k=>$v) 
     if($f = ! $f) 
     unset($a[$k]); 
    return $a; 
    } 

छोटी से छोटी संस्करण मैं बंद सोच सकता है कि।

+0

क्या आप कुछ याद नहीं कर रहे हैं? – deceze

+1

आपका अगर कथन दोस्त काम नहीं करेगा। –

-1

एक आवरण समारोह

function getInput($i) 
{ 
    global $input; 
    return $input[$i*2]; 
} 

बनाने सबसे छोटा और सबसे कुशल मुझे लगता है।

+2

यह निश्चित रूप से छोटा है, लेकिन यह क्या है? – deceze

+3

यक, ग्लोबल्स! : पी –

2

आप उपयोग कर रहे हैं (जो इस मामले ;-) में वैश्विक की तुलना में बेहतर नहीं है) PHP 5.3 या बाद में, या एसपीएल एक्सटेंशन स्थापित है (आप डिफ़ॉल्ट रूप से PHP 5 पर करेंगे), आप FilterIterator और ArrayObject कक्षाओं का उपयोग कर सकते हैं।

class EvenKeysFilter extends FilterIterator 
{ 
    private function iseven($keyval) 
    { 
     return (($keyval % 2) == 0); 
    } 

    public function accept() 
    { 
     $keyval = $this->getInnerIterator()->key(); 
     return ($this->iseven($keyval)); 
    } 
} 

$input = array('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j',); 
$inputobj = new ArrayObject($input); 

$evenFilterIter = new EvenKeysFilter($inputobj->getIterator());  
$output = iterator_to_array($evenFilterIter, false); 

print_r($output); 

(iterator_to_array() ओर इशारा करते हुए के लिए VolkerK को प्रॉप्स)

कौन सा सही ढंग से इस आउटपुट:

Array 
(
    [0] => a 
    [1] => c 
    [2] => e 
    [3] => g 
    [4] => i 
) 
+0

पता नहीं क्यों, लेकिन मुझे लगता है कि मुझे यह पसंद है! शायद इसे किसी एप्लिकेशन में उपयोग नहीं करना होगा किसी और को बनाए रखें, लेकिन मुझे निश्चित रूप से यह पसंद है (और एसपीएल के बारे में नहीं सोचा था)। धन्यवाद :-) (केवल एक '(' जिसे स्वीकृति विधि में हटा दिया जाना है, और फिर यह काम करता है) –

+0

मैं मानता हूं, एसपीएल शायद अधिक है इस मामले के लिए, लेकिन रिकर्सिवइटरेटर इटरेटर जैसी चीजें अमूल्य है। –

+0

यह बहुत बुरा है कि लोग (वास्तव में, वास्तव में) आमतौर पर एसपीएल का उपयोग नहीं करते हैं :-( –

संबंधित मुद्दे