मूल्य द्वारा PHP सरणी हटाना (कुंजी नहीं)


885

मेरे पास एक PHP सरणी है जो इस प्रकार है:

$messages = [312, 401, 1599, 3, ...];

मैं मूल्य $del_val(उदाहरण के लिए $del_val=401) वाले तत्व को हटाना चाहता हूं , लेकिन मुझे इसकी कुंजी नहीं पता है। यह मदद कर सकता है: प्रत्येक मूल्य केवल एक बार हो सकता है

मैं इस कार्य को करने के लिए सबसे सरल कार्य की तलाश कर रहा हूं, कृपया।


1
@ अदम स्ट्रुडविक लेकिन अगर आपके पास इस एरे पर कई डिलीट हैं, तो बेहतर होगा कि इसे एक बार इटरेट करें और मूल्य के बराबर इसकी कुंजी बनाएं?
डीज़ोना


जवाबों:


1565

का उपयोग करना array_search()और unset, निम्न प्रयास करें:

if (($key = array_search($del_val, $messages)) !== false) {
    unset($messages[$key]);
}

array_search()उस तत्व की कुंजी देता है, जिसे वह खोजता है, जिसका उपयोग करके उस तत्व को मूल सरणी से हटाया जा सकता है unset()। यह FALSEविफलता पर वापस आ जाएगा , हालांकि यह सफलता पर एक गलत-वाई मान लौटा सकता है (आपकी कुंजी 0उदाहरण के लिए हो सकती है), यही कारण है कि सख्त तुलना!== ऑपरेटर का उपयोग किया जाता है।

if()के विवरण की जांच करेंगे कि क्या array_search()एक मान दिया है, और अगर यह किया केवल एक कार्रवाई प्रदर्शन करेंगे।


14
क्या $ संदेश = array_diff ($ संदेश, सरणी ($ del_val)) भी काम करेंगे? क्या यह प्रदर्शन में बेहतर होगा?
एडम स्ट्रूडविक

9
@ अदम इसे बाहर का परीक्षण क्यों नहीं करते? मेरी भावना यह है कि array_diff()यह दो सरणियों की तुलना के रूप में धीमी है , बस एक तरह से खोज नहीं होगी array_search()
Bojangles

22
भले ही यह वैध है, आपको इस तरह के बयानों में मान देने से बचना चाहिए। यह केवल आपको परेशानी में डालेगा।
adlawson

17
क्या होगा अगर $keyहै 0?
इवान

16
यदि आप जिस मूल्य की खोज कर रहे हैं, उसके पास 0या किसी अन्य गलत मूल्य की कुंजी है , तो यह मूल्य को परेशान नहीं करेगा और आपका कोड काम नहीं करेगा। आपको परीक्षण करना चाहिए $key === false। (edit- you got it)
evan

671

खैर, एक तत्व को सरणी से हटाना मूल रूप से केवल एक तत्व के साथ अंतर सेट करना है।

array_diff( [312, 401, 15, 401, 3], [401] ) // removing 401 returns [312, 15, 3]

यह अच्छी तरह से सामान्यीकृत करता है, आप चाहें तो एक ही समय में जितने चाहें उतने तत्व निकाल सकते हैं।

अस्वीकरण: ध्यान दें कि मेरा हल पुराने उत्तर को स्वीकार किए गए उत्तर के विपरीत बरकरार रखते हुए सरणी की एक नई प्रति तैयार करता है। आपको जो चाहिए वो उठाओ।


32
यह केवल उन वस्तुओं के लिए काम करता है जिन्हें एक स्ट्रिंग में परिवर्तित किया जा सकता है
nischayn22

7
मुझे लगता है कि [$element]मैं array($element)इसके बजाय इस्तेमाल के लिए एक 'पार्स त्रुटि' हो रहा है । कोई बड़ी बात नहीं है, लेकिन बस किसी को भी ऐसा ही मुद्दा चाहिए था जो यह जान सके कि वे अकेले नहीं थे
अंगद

8
निश्चित रूप से, मैंने अनुमान लगाया है कि PHP 5.4 अब पुराने नोटेशन को छोड़ने के लिए बहुमत में है। टिप्पणी के लिए धन्यवाद।
रोक क्रज

22
यह ध्यान देने योग्य है कि किसी कारण से इसकी समानता की स्थिति के रूप में array_diffउपयोग होता है (string) $elem1 === (string) $elem2, न $elem1 === $elem2कि जैसा कि आप उम्मीद कर सकते हैं। @ Nischayn22 द्वारा बताया गया मुद्दा इसी का परिणाम है। यदि आप एक उपयोगिता फ़ंक्शन के रूप में उपयोग करना चाहते हैं जो कि मनमानी तत्वों (जो ऑब्जेक्ट्स हो सकते हैं) के सरणियों के लिए काम करेंगे, तो इस कारण से बोजंगल का जवाब बेहतर हो सकता है।
मार्क अमेरी

4
यह भी ध्यान दें कि यह विधि प्रत्येक तर्क के लिए आंतरिक रूप से एक प्रकार का कार्य करती है array_diff()और इस प्रकार O (n) से O (n lg n) तक रनटाइम को nudges करती है।
जेक

115

एक दिलचस्प तरीका उपयोग करके है array_keys():

foreach (array_keys($messages, 401, true) as $key) {
    unset($messages[$key]);
}

array_keys()समारोह (तुलना के लिए यानी का उपयोग कर ===) एक विशेष मूल्य के लिए और क्या सख्त जाँच की आवश्यकता है केवल चाबियाँ वापस जाने के लिए दो अतिरिक्त पैरामीटर लेता है।

यह समान मान (जैसे [1, 2, 3, 3, 4]) के साथ कई सरणी आइटम भी निकाल सकता है ।


3
@ blasteralfredΨ एक रैखिक खोज O (n) है; मुझे यकीन नहीं है कि आप ऐसा क्यों सोचते हैं कि यह एक समस्या है।
जाक

1
हां, यह कई सरणी आइटम / कुंजियों के चयन के लिए प्रभावी है।
ओकी एरी रिनाल्डी

3
यह सरणियों के लिए सबसे अच्छा है जिसमें सभी अद्वितीय मान शामिल नहीं हो सकते हैं।
डेरोकोरियन

समस्या यह है कि यह कुंजी के इंडेक्स को छोड़ देता है: [०] - ए, [२] - बी ([१] चला गया है लेकिन सरणी अभी भी याद आती है)
रोड्निको २६'१४ '

3
@ रोडोडिको जिस स्थिति में आपको आवश्यकता होगी array_values(); शेष कुंजियाँ अभी भी उसी क्रम में हैं, लेकिन तकनीकी रूप से यह "
अनसुलझा

55

यदि आप निश्चित रूप से जानते हैं कि आपके सरणी में उस मान के साथ केवल एक तत्व होगा, तो आप कर सकते हैं

$key = array_search($del_val, $array);
if (false !== $key) {
    unset($array[$key]);
}

यदि, हालांकि, आपका मान आपके सरणी में एक से अधिक बार हो सकता है, तो आप ऐसा कर सकते हैं

$array = array_filter($array, function($e) use ($del_val) {
    return ($e !== $del_val);
});

नोट: दूसरा विकल्प केवल Closures के साथ PHP5.3 + के लिए काम करता है


41
$fields = array_flip($fields);
unset($fields['myvalue']);
$fields = array_flip($fields);

11
यह केवल तभी काम करता है जब आपके एरे में डुप्लिकेट वैल्यूज़ न हों जिन्हें आप हटाने की कोशिश कर रहे हैं।
जर्कुलो

2
@jberculo और कभी-कभी कि वास्तव में आपको क्या जरूरत है, कुछ मामलों में यह मुझे इस पर एक सरणी करने से बचाता है aswel
DarkMukke

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

संदेश में कहा गया है "प्रत्येक मूल्य केवल एक बार ही हो सकता है" यह काम करना चाहिए। यह अच्छा होता अगर पोस्टर में smae वैरिएबल के नामों का उपयोग होता, हालांकि और थोड़ा अन्वेषण किया जाता
Raatje

2
जाहिर है यह चयनित समाधान की तुलना में सबसे तेज़ है, मैंने छोटी बेंचमार्किंग की।
AMB

28

निम्नलिखित कोड पर एक नज़र है:

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

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

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

और यह आपको यह सरणी मिलेगी:

array('nice_item', 'another_liked_item')

1
साहचर्य सरणियों के लिए आपको array_diff_assoc () का उपयोग करना होगा
theCodeMachine

5
यह इस उत्तर से अलग कैसे है ?
random_user_name

26

सबसे अच्छा तरीका है array_splice

array_splice($array, array_search(58, $array ), 1);

बेस्ट का कारण यहाँ है :


4
यह साहचर्य सरणियों और सरणियों पर काम नहीं करेगा, जिनकी कुंजी में अंतराल हैं, जैसे [1, 2, 4 => 3]
जेक

कोई खेद नहीं यह काम करेगा। कृपया लेख मैं लिंक प्रदान किया है पढ़ें
Airy

4
यह नहीं होगा मेरी उपरोक्त टिप्पणी की सरणी पर विचार करें; जब मैं मूल्य निकालने के लिए आपके कोड का उपयोग करता हूं 3, तो सरणी होगी [1, 2, 3]; दूसरे शब्दों में, मान हटाया नहीं गया था। स्पष्ट होने के लिए, मैं यह नहीं कह रहा हूं कि यह सभी स्थितियों में विफल है, बस यह एक है।
जेक

1
array_splice सबसे अच्छा तरीका है, हटाए जाने के बाद
परेशान

21

या बस, मैनुअल तरीका:

foreach ($array as $key => $value){
    if ($value == $target_value) {
        unset($array[$key]);
    }
}

यह उनमें से सबसे सुरक्षित है क्योंकि आपके पास अपने सरणी पर पूर्ण नियंत्रण है


1
के array_splice()बजाय का उपयोग करना unset()सरणी अनुक्रमित को भी फिर से व्यवस्थित करेगा, जो इस मामले में बेहतर हो सकता है।
डेनियल ऑरलैंडो

20

निम्नलिखित कोड के द्वारा, दोहराए गए मूल्यों को $ संदेशों से हटा दिया जाएगा।

$messages = array_diff($messages, array(401));


3
ऊपर मतदान किया। यह पहले से ही अन्य उत्तरों में से था, लेकिन आप इसे सरल रखते हुए सबसे अच्छे से कहते हैं, जैसा कि आपके पास है। इसका जवाब बस "array_diff" है
ghbarratt

1
सरल दिखता है लेकिन यह O (n) से O (n lg n) में जटिलता को बदलता है। तो, यह वास्तव में और अधिक जटिल है;)
क्रिज़िस्तोफ़ प्रिज़गोडा

20

यदि आपके पास PHP है 5.3+, तो एक पंक्ति कोड है:

$array = array_filter($array, function ($i) use ($value) { return $i !== $value; }); 

क्या आपको यकीन है? उस क्लोजर तक पहुंच नहीं है $value, इसलिए वास्तव में इसे एक मिनी क्लास में रखा जाना चाहिए ताकि आप $valueक्लोजर के भीतर एक्सेस कर सकें ....
random_user_name

@ cale_b, मैंने उदाहरण को अद्यतन किया है। इसके अलावा यहाँ रेफरी है: php.net/manual/en/functions.anonymous.php
डेविड लिन

3
यदि आप इसे "एक पंक्ति कोड" कहते हैं, तो आप अपना पूरा कोडबेस एक लाइन पर लिख सकते हैं
मिलन शिमेक

16
function array_remove_by_value($array, $value)
{
    return array_values(array_diff($array, array($value)));
}

$array = array(312, 401, 1599, 3);

$newarray = array_remove_by_value($array, 401);

print_r($newarray);

उत्पादन

Array ( [0] => 312 [1] => 1599 [2] => 3 )


2
मुझे यकीन नहीं है कि यह तेज है क्योंकि इस समाधान में कई फ़ंक्शन कॉल शामिल हैं।
जूलियन पाओलो दयाग

13

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

unset($messages[array_flip($messages)['401']]);

व्याख्या : 401सरणी को फ़्लिप करने के बाद जिस तत्व की कुंजी है उसे हटा दें ।


यदि आप राज्य को संरक्षित करना चाहते हैं तो आपको बहुत सावधान रहना होगा। क्योंकि भविष्य के सभी कोड में कुंजियों के बजाय मान होना चाहिए।
सादुलु

1
@saadlulu $ मैसेज एरे को फ़्लिप नहीं किया जाएगा क्योंकि array_flip () ओरिजिनल ऐरे पर असर नहीं करता है, इसलिए पिछली लाइन अप्लाई करने के बाद रिजल्ट वाली ऐरे समान होगी, सिवाय इसके कि अनचाहे रिजल्ट को हटा दिया जाएगा।
क़ुरैशी

2
सुनिश्चित नहीं है कि अगर यह सही है, तो क्या होगा यदि मूल्य के साथ कई तत्व हैं 401?
Zippp

यह अभी भी चाबियाँ संरक्षित करेगा।
Szabolcs Páll


6

अंडरस्कोर का तर्क उधार लिया। JS _.reject और दो फ़ंक्शन बनाए (लोग कार्यों को पसंद करते हैं !!)

array_reject_value: यह फ़ंक्शन केवल निर्दिष्ट मान को अस्वीकार कर रहा है (PHP4,5,7 के लिए भी काम करता है)

function array_reject_value(array &$arrayToFilter, $deleteValue) {
    $filteredArray = array();

    foreach ($arrayToFilter as $key => $value) {
        if ($value !== $deleteValue) {
            $filteredArray[] = $value;
        }
    }

    return $filteredArray;
}

array_reject: यह फ़ंक्शन केवल कॉल करने योग्य विधि को अस्वीकार कर रहा है (PHP के लिए काम करता है = = 5.3)

function array_reject(array &$arrayToFilter, callable $rejectCallback) {

    $filteredArray = array();

    foreach ($arrayToFilter as $key => $value) {
        if (!$rejectCallback($value, $key)) {
            $filteredArray[] = $value;
        }
    }

    return $filteredArray;
}

तो हमारे वर्तमान उदाहरण में हम उपरोक्त कार्यों का उपयोग इस प्रकार कर सकते हैं:

$messages = [312, 401, 1599, 3, 6];
$messages = array_reject_value($messages, 401);

या इससे भी बेहतर: (यह हमें एक बेहतर सिंटैक्स देता है जैसे कि array_filter एक का उपयोग करने के लिए )

$messages = [312, 401, 1599, 3, 6];
$messages = array_reject($messages, function ($value) {
    return $value === 401;
});

उपरोक्त का उपयोग अधिक जटिल सामान के लिए किया जा सकता है जैसे मान लें कि हम उन सभी मूल्यों को हटाना चाहते हैं जो 401 या उससे अधिक के बराबर हैं जिन्हें हम नहीं कर सकते हैं:

$messages = [312, 401, 1599, 3, 6];
$greaterOrEqualThan = 401;
$messages = array_reject($messages, function ($value) use $greaterOrEqualThan {
    return $value >= $greaterOrEqualThan;
});

1
क्या यह रीइन्वेस्टिंग फ़िल्टर नहीं है? php.net/manual/en/function.array-filter.php
रिचर्ड

हाँ सचमुच। जैसा कि मैं पहले ही पोस्ट पर कह रहा हूं "या इससे भी बेहतर: (जैसा कि यह हमें array_filter एक की तरह उपयोग करने के लिए एक बेहतर सिंटैक्स देता है)"। कभी-कभी आपको वास्तव में फ़ंक्शन को अंडरस्कोर के रूप में अस्वीकार करने की आवश्यकता होती है और यह वास्तव में फ़िल्टर के ठीक विपरीत है (और आपको इसे कम से कम कोड के साथ प्राप्त करने की आवश्यकता है)। यही कार्य कर रहे हैं। मूल्यों को अस्वीकार करने का यह एक सरल तरीका है।
जॉन स्काउबोरडिस

6
$array = array("apple", "banana",'mango');
$array = array_filter($array, function($v) { return $v != "apple"; });

यह कोशिश करो, यह मूल्य द्वारा तत्व को निकालने का सबसे अच्छा और सबसे तेज़ तरीका है


5

@Bojangles जवाब ने मेरी मदद की। धन्यवाद।

मेरे मामले में, सरणी सहयोगी हो सकती है या नहीं, इसलिए मैंने निम्नलिखित फ़ंक्शन को जोड़ा

function test($value, $tab) {

 if(($key = array_search($value, $tab)) !== false) {
    unset($tab[$key]); return true;

 } else if (array_key_exists($value, $tab)){
        unset($tab[$value]); return true;

 } else {
    return false; // the $value is not in the array $tab
 }

}

सादर



4

स्वीकृत उत्तर सरणी को साहचर्य सरणी में परिवर्तित करता है, इसलिए, यदि आप इसे स्वीकृत उत्तर के साथ गैर-सहयोगी सरणी के रूप में रखना चाहते हैं, तो आपको array_valuesभी उपयोग करना पड़ सकता है ।

if(($key = array_search($del_val, $messages)) !== false) {
    unset($messages[$key]);
    $arr = array_values($messages);
}

संदर्भ यहाँ है


4

आपकी आवश्यकता के अनुसार " प्रत्येक मूल्य केवल एक बार के लिए हो सकता है " यदि आप अपने सरणी में अद्वितीय मूल्यों को रखने में रुचि रखते हैं, तो वही array_unique()हो सकता है जो आप खोज रहे हैं।

इनपुट:

$input = array(4, "4", "3", 4, 3, "3");
$result = array_unique($input);
var_dump($result);

परिणाम:

array(2) {
  [0] => int(4)
  [2] => string(1) "3"
}

4

यदि आप जिन मूल्यों को हटाना चाहते हैं, वे हैं, या किसी सरणी में हो सकते हैं। Array_diff फ़ंक्शन का उपयोग करें । इस तरह चीजों के लिए महान काम करने लगता है।

array_diff

$arrayWithValuesRemoved = array_diff($arrayOfData, $arrayOfValuesToRemove);

1
यह इस उत्तर से अलग कैसे है ?
random_user_name

4

मुझे पता है कि यह सब कुशल नहीं है, लेकिन सरल, सहज और पढ़ने में आसान है।
इसलिए अगर कोई ऐसा नहीं खोज रहा है, जो फैंसी समाधानों के लिए और अधिक मूल्यों या अधिक विशिष्ट परिस्थितियों के साथ काम करने के लिए बढ़ाया जा सकता है .. तो यहां एक सरल कोड है:

$result = array();
$del_value = 401;
//$del_values = array(... all the values you don`t wont);

foreach($arr as $key =>$value){
    if ($value !== $del_value){
        $result[$key] = $value;
    }

    //if(!in_array($value, $del_values)){
    //    $result[$key] = $value;
    //}

    //if($this->validete($value)){
    //      $result[$key] = $value;
    //}
}

return $result

4

साथ सरणी कुंजी प्राप्त करें array_search()


2
यदि I और इसे array_search के साथ पाया जाए तो ही मैं मान को कैसे हटाऊं?
एडम स्ट्रुडविक

3
$ k = array_search ($ सुई, $ घास का ढेर, सच); if ($ k! == false) {unset ($ haystack [$ k]); }
evan

3

यदि आपको इसकी कुंजी पता नहीं है तो इसका मतलब है कि यह मायने नहीं रखता है।

आप मान को कुंजी के रूप में रख सकते हैं, इसका मतलब है कि यह तुरंत मूल्य ढूंढ लेगा। बार-बार सभी तत्वों में खोज का उपयोग करने से बेहतर है।

$messages=array();   
$messages[312] = 312;    
$messages[401] = 401;   
$messages[1599] = 1599;   
$messages[3] = 3;    

unset($messages[3]); // no search needed

केवल उन वस्तुओं के लिए काम करता है जिन्हें स्ट्रिंग में परिवर्तित किया जा सकता है।
एमिल बर्जरॉन

2

orऑपरेटर का उपयोग कर एक-लाइनर :

($key = array_search($del_val, $messages)) !== false or unset($messages[$key]);

2

आप इस URL को देख सकते हैं : फ़ंक्शन के लिए

array-diff-key()

<?php
$array1 = array('blue'  => 1, 'red'  => 2, 'green'  => 3, 'purple' => 4);
$array2 = array('green' => 5, 'blue' => 6, 'yellow' => 7, 'cyan'   => 8);

var_dump(array_diff_key($array1, $array2));
?>

फिर आउटपुट होना चाहिए,

array(2) {
  ["red"]=>
  int(2)
  ["purple"]=>
  int(4)
}

1

एक सरणी के मूल्य को हटाने के लिए एक और विचार, array_diff का उपयोग करें। अगर मै चाहू तो

$my_array = array(1=>"a", "second_value"=>"b", 3=>"c", "d");
$new_array_without_value_c = array_diff($my_array, array("c"));

(डॉक्टर: http://php.net/manual/fr/function.array-diff.php )


3
यह इस उत्तर से अलग कैसे है ?
random_user_name

1

मुझे लगता है कि सबसे आसान तरीका होगा कि आप फॉर्क लूप के साथ फंक्शन का उपयोग करें:

//This functions deletes the elements of an array $original that are equivalent to the value $del_val
//The function works by reference, which means that the actual array used as parameter will be modified.

function delete_value(&$original, $del_val)
{
    //make a copy of the original, to avoid problems of modifying an array that is being currently iterated through
    $copy = $original;
    foreach ($original as $key => $value)
    {
        //for each value evaluate if it is equivalent to the one to be deleted, and if it is capture its key name.
        if($del_val === $value) $del_key[] = $key;
    };
    //If there was a value found, delete all its instances
    if($del_key !== null)
    {
        foreach ($del_key as $dk_i)
        {
            unset($original[$dk_i]);
        };
        //optional reordering of the keys. WARNING: only use it with arrays with numeric indexes!
        /*
        $copy = $original;
        $original = array();
        foreach ($copy as $value) {
            $original[] = $value;
        };
        */
        //the value was found and deleted
        return true;
    };
    //The value was not found, nothing was deleted
    return false;
};

$original = array(0,1,2,3,4,5,6,7,4);
$del_val = 4;
var_dump($original);
delete_value($original, $del_val);
var_dump($original);

आउटपुट होगा:

array(9) {
  [0]=>
  int(0)
  [1]=>
  int(1)
  [2]=>
  int(2)
  [3]=>
  int(3)
  [4]=>
  int(4)
  [5]=>
  int(5)
  [6]=>
  int(6)
  [7]=>
  int(7)
  [8]=>
  int(4)
}
array(7) {
  [0]=>
  int(0)
  [1]=>
  int(1)
  [2]=>
  int(2)
  [3]=>
  int(3)
  [5]=>
  int(5)
  [6]=>
  int(6)
  [7]=>
  int(7)
}

1

PHP 7.4 के साथ एरो फ़ंक्शंस का उपयोग करना:

$messages = array_filter($messages, fn ($m) => $m != $del_val);

इसे गैर-सहयोगी सरणी के साथ रखने के लिए इसे इसके साथ लपेटें array_values():

$messages = array_values(array_filter($messages, fn ($m) => $m != $del_val));
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.