मान द्वारा सरणी आइटम निकालना


166

मुझे दिए गए मान के साथ सरणी आइटम निकालने की आवश्यकता है:

if (in_array($id, $items)) {
    $items = array_flip($items);
    unset($items[ $id ]);
    $items = array_flip($items);
}

यह कम (अधिक कुशल) तरीके से किया जा सकता है?


जवाबों:


423

यह एक साधारण एक-लाइनर के साथ पूरा किया जा सकता है।

इस सरणी होने:

$arr = array('nice_item', 'remove_me', 'another_liked_item', 'remove_me_also');

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

$arr = array_diff($arr, array('remove_me', 'remove_me_also'));

और का मूल्य $arrहोगा:

array('nice_item', 'another_liked_item')

आशा है कि यह सुंदर कोड लिखने में मदद करता है।


2
नहीं, यह करता है संदर्भित सरणियों के साथ काम करता है, array_diffसमारोह गैर विनाशकारी है, यह एक नई सरणी देता है।
अलेजांद्रो गार्सिया इग्लेसियस

2
@srcspider क्यों नहीं? $referenced = array_diff($referenced, $items_to_remove);
अलेजांद्रो गार्सिया इग्लेसियस

1
$ संदर्भित अब एक नए सरणी की ओर इशारा कर रहा है, जिस सरणी को आप बदलना चाहते थे, उसमें अभी भी पुराने मूल्य हैं।
srcspider

2
@srcspider अच्छा, आप मुझे बताएं कि यहां क्या चल रहा है ... codepad.org/11ZhiFP0
एलेजांद्रो गार्सिया इग्लेसियस

1
मेरी गलती; php का वैरिएबल अलियासिंग नौटंकी हमेशा मुझे>>।>
srcspider

37

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

$arr = array(0 => 123456);
for($i = 1; $i < 500000; $i++) {
    $arr[$i] = rand(0,PHP_INT_MAX);
}

shuffle($arr);
$arr2 = $arr;
$arr3 = $arr;

/** 
 * Method 1 - array_search()
 */
$start = microtime(true);
while(($key = array_search(123456,$arr)) !== false) {
    unset($arr[$key]);
}
echo count($arr). ' left, in '.(microtime(true) - $start).' seconds<BR>';

/** 
 * Method 2 - basic loop
 */
$start = microtime(true);
foreach($arr2 as $k => $v) {
    if ($v == 123456) {
        unset($arr2[$k]);
    }
}
echo count($arr2). 'left, in '.(microtime(true) - $start).' seconds<BR>';

/** 
 * Method 3 - array_keys() with search parameter
 */
$start = microtime(true);
$keys = array_keys($arr3,123456);
foreach($keys as $k) {
    unset($arr3[$k]);
}
echo count($arr3). 'left, in '.(microtime(true) - $start).' seconds<BR>';

तीसरा तरीका, array_keys()वैकल्पिक खोज पैरामीटर निर्दिष्ट के साथ, अब तक की सबसे अच्छी विधि है। आउटपुट उदाहरण:

499999 left, in 0.090957164764404 seconds
499999left, in 0.43156313896179 seconds
499999left, in 0.028877019882202 seconds

इसे देखते हुए, जो समाधान मैं उपयोग करूंगा वह होगा:

$keysToRemove = array_keys($items,$id);
foreach($keysToRemove as $k) {
    unset($items[$k]);
}

मुझे लगता है कि array_search array_diff विधि का उपयोग करने की तुलना में बहुत अधिक पठनीय कोड है। वोट दें
kendepelchin

@ ज़ोम्बैट मुझे आश्चर्य है कि अगर आदेश का परिणामों से कोई लेना-देना है। यह संभव है कि फेरबदल मूल्य को हम या तो सामने या अंत के करीब खोज रहे हैं। इसके अलावा ... +1
जनरल रेडनेक

31

कैसा रहेगा:

if (($key = array_search($id, $items)) !== false) unset($items[$key]);

या कई मूल्यों के लिए:

while(($key = array_search($id, $items)) !== false) {
    unset($items[$key]);
}

यह महत्वपूर्ण नुकसान को भी रोकेगा, जो इसका एक दुष्प्रभाव है array_flip()


1
काम नहीं करेगा अगर $ id पहली सरणी तत्व है, तो इस तरह से बेहतर होगा: यदि (($ key = array_search ($ id, $ आइटम))! == गलत) अनसेट ($ आइटम [$ कुंजी]);
मारेक


8

सबसे शक्तिशाली समाधान का उपयोग किया जाएगा array_filter , जो आपको अपने स्वयं के फ़िल्टरिंग फ़ंक्शन को परिभाषित करने की अनुमति देता है।

लेकिन कुछ लोग कह सकते हैं कि यह आपकी स्थिति में थोड़ा भारी
हैforeach सरणी को गर्त में जाने के लिए और जो आइटम आप नहीं चाहते हैं उसे निकालने के लिए लूप पर्याप्त होना चाहिए।

कुछ इस तरह, आपके मामले में, शायद यह चाल चलनी चाहिए:

foreach ($items as $key => $value) {
    if ($value == $id) {
        unset($items[$key]);
        // If you know you only have one line to remove, you can decomment the next line, to stop looping
        //break;
    }
}

6

Array_search () आज़माएँ


3
मैं सिर्फ प्रलेखन पढ़ता हूं, और यह मान से जुड़े सभी कुंजी खोजने के लिए array_keys () का उपयोग करने की सलाह देता है।
सेवेजमैन

@ सावेजमैन - सहमत। मैंने एक त्वरित बेंचमार्क चलाया और इस कार्य के लिए array_keys()बेहतर प्रदर्शन किया array_search()
zombat

6

आपके समाधान केवल तभी काम करते हैं जब आपके सरणी में अद्वितीय मूल्य हों

देख:

<?php
$trans = array("a" => 1, "b" => 1, "c" => 2);
$trans = array_flip($trans);
print_r($trans);
?>

एक बेहतर तरीका एक लूप में सरणी_search के साथ , यदि कोई पेचीदा हो तो परेशान हो जाएगा।


तुम ठीक कह रहे हैं, लेकिन इस विशेष मामले में मैं बहुत यकीन है कि मूल्यों अद्वितीय हैं :) हूँ
मारेक

5

w / o फ्लिप:

<?php
foreach ($items as $key => $value) {
    if ($id === $value) {
        unset($items[$key]);
    }
}


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