PHP में बहुआयामी सरणी से डुप्लिकेट मान कैसे निकालें


306

मैं PHP में बहु-आयामी सरणी से डुप्लिकेट मान कैसे निकाल सकता हूं?

उदाहरण सरणी:

Array
(
    [0] => Array
    (
        [0] => abc
        [1] => def
    )

    [1] => Array
    (
        [0] => ghi
        [1] => jkl
    )

    [2] => Array
    (
        [0] => mno
        [1] => pql
    )

    [3] => Array
    (
        [0] => abc
        [1] => def
    )

    [4] => Array
    (
        [0] => ghi
        [1] => jkl
    )

    [5] => Array
    (
        [0] => mno
        [1] => pql
    )

)

जवाबों:


637

यहाँ एक और तरीका है। कोई मध्यवर्ती चर सहेजे नहीं जाते हैं।

हमने विभिन्न प्रकार के अतिव्यापी प्रश्नों से परिणामों को डी-डुप्लिकेट करने के लिए इसका उपयोग किया।

$input = array_map("unserialize", array_unique(array_map("serialize", $input)));

23
गैर-मान्यता के कारण यह धीमा है और बड़ा और अधिक जटिल है और सरणी अधिक जटिल है। एक कारण है कि मैंने array_intersect_key (इस उत्तर से आधे साल पहले) का उपयोग किया है।
OIS

11
@ ओआईएस ने अच्छी तरह से इसका परीक्षण किया, एक टाइपो था, लेकिन यह काम करता है .. धन्यवाद दोस्त !: $ no_duplicates = array_intersect_key ($ array, array_unique (array_map ('serialize', $ array)));
trevorkavanaugh

3
यदि आप अनुक्रमणिका को निरंतर चाहते हैं, तो array_values ​​अर्थात $ input = array_values ​​(array_map ("unserialize", array_unique (array_map ("serialize", $ input)))) का उपयोग करें;
lbsweek

4
आजकल आप शायद PHP सीरियल के बजाय json_encode और json_decode का विकल्प चुनेंगे। प्रदान किए गए मूल्यों के लिए लाभ होना चाहिए और आप PHP सीरियलाइज़ेशन विवरणों में नहीं चलते हैं जो जहाजों को क्रमबद्ध / अनसुना करते हैं और सबसे अधिक संभावना अवांछित हैं।
हकर्रे

2
खबरदार कि serialize(array('a' => '1', 'b' => '1'))से अलग है serialize(array('b' => '1', 'a' => '1'))। के रूप में setsया उपयोग किए गए सरणियों के लिए यह विकल्प विफल हो जाएगा (hash)maps
एंड्रास गियोम्रे

240

array_unique()यदि आप SORT_REGULARध्वज का उपयोग करते हैं तो 5.2.9 के बाद से आप इसका उपयोग कर सकते हैं :

array_unique($array, SORT_REGULAR);

यह फ़ंक्शन को समानता के लिए तत्वों की तुलना करता है जैसे कि $a == $bउपयोग किया जा रहा था, जो आपके मामले के लिए एकदम सही है।

उत्पादन

Array
(
    [0] => Array
        (
            [0] => abc
            [1] => def
        )

    [1] => Array
        (
            [0] => ghi
            [1] => jkl
        )

    [2] => Array
        (
            [0] => mno
            [1] => pql
        )

)

हालाँकि, ध्यान रखें कि प्रलेखन राज्यों:

array_unique() बहु आयामी सरणियों पर काम करने का इरादा नहीं है।


2
मुझे लगता है कि यह स्वीकार किए जाते हैं की तुलना में अधिक त्वरित और अधिक स्पष्ट समाधान है! यह एक वोट देता है! :) हम्म साइट पर हम्म यह देख सकते हैं कि यह इतनी जल्दी नहीं है, जैसा कि मैंने सोचा ...
एंडरसन

4
डुप्लिकेट सरणियों को निकालने के लिए SORT_REGULAR ध्वज का उपयोग करना अजीब बात है।
स्टीफन

4
@Stefan तुम सही हो; यह सही परिणाम नहीं देता है, लेकिन यह शायद एक बग है क्योंकि यह PHP 7 = /
Ja 30ck

4
यह मेरे मामले में भी काम करता प्रतीत होता है, लेकिन क्या इस नोट से कोई अन्य व्यक्ति array_unique () डॉक में परेशान है? php.net/manual/en/…
हिक्स

2
@ जॅक यू आर राइट यह एक बग है जैसा कि PHP 5.6.23: eval.in/645675 लेकिन PHP 7.0.8 के रूप में तय किया गया है: eval.in/645676
Zack Morris

63

मुझे इसी तरह की समस्या थी लेकिन मुझे इसके लिए 100% काम करने का हल मिला।

<?php
    function super_unique($array,$key)
    {
       $temp_array = [];
       foreach ($array as &$v) {
           if (!isset($temp_array[$v[$key]]))
           $temp_array[$v[$key]] =& $v;
       }
       $array = array_values($temp_array);
       return $array;

    }


$arr="";
$arr[0]['id']=0;
$arr[0]['titel']="ABC";
$arr[1]['id']=1;
$arr[1]['titel']="DEF";
$arr[2]['id']=2;
$arr[2]['titel']="ABC";
$arr[3]['id']=3;
$arr[3]['titel']="XYZ";

echo "<pre>";
print_r($arr);
echo "unique*********************<br/>";
print_r(super_unique($arr,'titel'));

?>

1
यह एक अलग सवाल का जवाब देता है। यहाँ देखें: stackoverflow.com/questions/4585208/…
OIS

शानदार समारोह! और यदि आप वस्तुओं के साथ काम कर रहे हैं: अगर (! ($ $ -> $ v -> $ कुंजी)) $ सरणी [$ v -> $ कुंजी] = & $ v;
प्लेनॉक्स

35

दूसरा रास्ता। कुंजी के रूप में अच्छी तरह से संरक्षित करेगा।

function array_unique_multidimensional($input)
{
    $serialized = array_map('serialize', $input);
    $unique = array_unique($serialized);
    return array_intersect_key($input, $unique);
}

बड़े सरणियों के लिए, यह विधि अक्सर स्वीकृत उत्तर की तुलना में कम से कम 50% तेज होती है।
लोरियन ब्रुने

21

Array_unique () प्रलेखन पर उपयोगकर्ता टिप्पणियों के पास इसके कई समाधान हैं। उनमें से एक यहां पर है:

kbrbnsn पर rbnsn डॉट कॉम
27-Sep-2005 12:09

फिर भी एक और Array_Unique बहु-डिमांडेड सरणियों के लिए। मैंने केवल दो-डेमेजेड एरेज़ पर इसका परीक्षण किया है, लेकिन इसे संभवतः अधिक के लिए सामान्यीकृत किया जा सकता है, या पुनरावृत्ति का उपयोग करने के लिए बनाया जा सकता है।

यह फ़ंक्शन काम करने के लिए क्रमबद्ध, array_unique, और कार्य को अनसुना करता है।


function multi_unique($array) {
    foreach ($array as $k=>$na)
        $new[$k] = serialize($na);
    $uniq = array_unique($new);
    foreach($uniq as $k=>$ser)
        $new1[$k] = unserialize($ser);
    return ($new1);
}

यह http://ca3.php.net/manual/en/function.array-unique.php#57202 से है


18

यदि "डुप्लिकेट को हटाएं" का अर्थ है "डुप्लिकेट को हटा दें, लेकिन एक को वहां दें", एक समाधान array_unique(...)पहले "पहचानकर्ता कॉलम" पर लागू हो सकता है और फिर मूल सरणी में सभी कुंजियों को हटाने के लिए हो सकता है, जिसे कॉलम सरणी से हटा दिया गया है :

$array = [
    [
        'id' => '123',
        'foo' => 'aaa',
        'bar' => 'bbb'
    ],
    [
        'id' => '123',
        'foo' => 'ccc',
        'bar' => 'ddd'
    ],
    [
        'id' => '567',
        'foo' => 'eee',
        'bar' => 'fff'
    ]
];

$ids = array_column($array, 'id');
$ids = array_unique($ids);
$array = array_filter($array, function ($key, $value) use ($ids) {
    return in_array($value, array_keys($ids));
}, ARRAY_FILTER_USE_BOTH);

परिणाम है:

Array
(
    [0] => Array
        (
            [id] => 123
            [foo] => aaa
            [bar] => bbb
        )

    [2] => Array
        (
            [id] => 567
            [foo] => eee
            [bar] => fff
        )

)

18
Array
(
    [0] => Array
        (
            [id] => 1
            [name] => john
        )

    [1] => Array
        (
            [id] => 2
            [name] => smith
        )

    [2] => Array
        (
            [id] => 3
            [name] => john
        )

    [3] => Array
        (
            [id] => 4
            [name] => robert
        )

)

$temp = array_unique(array_column($array, 'name'));
$unique_arr = array_intersect_key($array, $temp);

यह डुप्लिकेट नामों को सरणी से हटा देगा। कुंजी द्वारा अद्वितीय


सुनिश्चित करें कि $arrayकुंजी "0" पर शुरू होती है। $arrayयदि $arrayकिसी पूर्व सरणी हेरफेर का परिणाम है, तो यह संभव है कि दूसरे नंबर पर शुरू हो । array_valuesकुंजियों को "0" पर वापस करने के लिए उपयोग करें
स्टीववेन्स


4

बस दूसरे पैरामीटर के रूप में SORT_REGULAR विकल्प का उपयोग करें।

$uniqueArray = array_unique($array, SORT_REGULAR);

1
SORT_REGULAR केवल PHP 7 में काम करता है क्योंकि PHP 5 में बग है (हालाँकि @ r3wt दस्तावेज़ीकरण के अनुसार सही है), मेरे जवाब को एक ज्वलनशील उदाहरण के लिए जवाब में देखें stackoverflow.com/questions/307674/-
Zack Morris

आप इसे क्यों जोड़ेंगे? यह इस उत्तर के समान है, जो आपके से एक वर्ष से अधिक पुराना है: stackoverflow.com/a/18373723/870729
random_user_name

3

यदि आपको विशिष्ट कुंजियों पर डुप्लिकेट को समाप्त करने की आवश्यकता है, जैसे कि एक mysqli आईडी, तो यहां एक सरल कवक है

function search_array_compact($data,$key){
    $compact = [];
    foreach($data as $row){
        if(!in_array($row[$key],$compact)){
            $compact[] = $row;
        }
    }
    return $compact;
}

बोनस अंक आप कुंजियों की एक सरणी को पास कर सकते हैं और एक बाहरी फ़ॉरेस्ट जोड़ सकते हैं, लेकिन यह 2x कुंजी प्रति अतिरिक्त धीमी होगी।


3

यूनिक मल्टी डाइमेंशन एरे का एक बहुत आसान और तार्किक तरीका इस प्रकार है,

यदि आपके पास इस तरह से सरणी है:

Array
(
    [Key1] => Array
        (
            [0] => Value1
            [1] => Value2
            [2] => Value1
            [3] => Value3
            [4] => Value1
        )
    [Key2] => Array
        (
            [0] => Value1
            [1] => Value2
            [2] => Value1
            [3] => Value3
            [4] => Value4
        )
)

foreachइसे हल करने के लिए उपयोग करें:

foreach($array as $k=>$v){
    $unique=array_unique($v);
    $array[$k]=$unique;
}

यह आपको निम्नलिखित परिणाम देगा:

Array
(
    [Key1] => Array
        (
            [0] => Value1
            [1] => Value2
            [3] => Value3
        )
    [Key2] => Array
        (
            [0] => Value1
            [1] => Value2
            [3] => Value3
            [4] => Value4
        )
)

और यदि आप कुंजियों के क्रम को पुनर्व्यवस्थित करना चाहते हैं,

foreach($array as $k=>$v){
    $unique= array_values(array_unique($v));
    $array[$k]=$unique;
}

यह ऑपरेशन आपको इस तरह से महत्वपूर्ण मान देगा:

Array
(
    [Key1] => Array
        (
            [0] => Value1
            [1] => Value2
            [2] => Value3
        )
    [Key2] => Array
        (
            [0] => Value1
            [1] => Value2
            [2] => Value3
            [3] => Value4
        )
)

मुझे उम्मीद है कि इससे सबकुछ साफ हो जाएगा।


2

यदि आपके पास इस तरह से एक सरणी है:

(उपयोगकर्ता सरणी का नाम है)

Array=>
 [0] => (array)
   'user' => 'john'
   'age' => '23'
 [1] => (array)
  'user' => 'jane'
  'age' => '20'
 [2]=> (array)
  'user' => 'john'
  'age' => '23'

और आप डुप्लिकेट हटाना चाहते हैं ... फिर:

$serialized = array();
for ($i=0; $i < sizeof($users); $i++) { 
  $test = in_array($users['user'], $serialized);
    if ($test == false) {
      $serialized[] = $users['user'];
    }
 }

एक समाधान हो सकता है: पी


1

समाधान पढ़ने में आसान, शायद सबसे कुशल नहीं:

function arrayUnique($myArray){
    if(!is_array($myArray))
        return $myArray;

    foreach ($myArray as &$myvalue){
        $myvalue=serialize($myvalue);
    }

    $myArray=array_unique($myArray);

    foreach ($myArray as &$myvalue){
        $myvalue=unserialize($myvalue);
    }

    return $myArray;

} 

1

जैसा कि लोग कह रहे हैं कि array_unique()यह बहुत धीमा है, यहां एक स्निपेट है जिसका उपयोग मैं एक स्तर के बहुआयामी सरणी के लिए करता हूं।

$serialized_array = array_map("serialize", $input);

foreach ($serialized_array as $key => $val) {
     $result[$val] = true;
}

$output = array_map("unserialize", (array_keys($result)));

संदर्भ पहले उपयोगकर्ता ने php.net में फ़ंक्शन पेज पर ध्यान दियाarray_unique()


अनुज, क्या आप अपना उत्तर संपादित कर सकते हैं? एक बग है। इसे समाप्त होना चाहिए $output = array_map('unserialize', array_keys($result));
कीबोर्डस्मैशर

@keyboardSmasher आपके इनपुट के लिए धन्यवाद। मैंने बदलाव किए और अब यह काम करता है। :)
अनुज

1

बहुत से लोगों ने मुझसे पूछा कि कैसे अद्वितीय बहुआयामी सरणी बनाया जाए। मैंने आपकी टिप्पणी से संदर्भ लिया है और यह मेरी मदद करता है।

सबसे पहले, आपके समाधान के लिए @jeromegamez @daveilers को धन्यवाद। लेकिन हर बार जब मैंने जवाब दिया, तो उन्होंने मुझसे पूछा कि यह 'सीरीज़' और 'अनसेरिज़ल' कैसे काम करता है। इसलिए मैं इसका कारण आपके साथ साझा करना चाहता हूं ताकि इससे अधिक लोगों को इसके पीछे की अवधारणा को समझने में मदद मिले।

मैं समझा रहा हूं कि हम चरणों में 'सीरियलाइज़' और 'अस्वाभाविक' का उपयोग क्यों करते हैं:

चरण 1: बहुआयामी सरणी को एक-आयामी सरणी में बदलें

बहुआयामी सरणी को एक-आयामी सरणी में परिवर्तित करने के लिए, पहले सरणी के अंदर सभी तत्वों (नेस्टेड सरणियों सहित) की बाइट स्ट्रीम प्रतिनिधित्व उत्पन्न करें। क्रमबद्ध () फ़ंक्शन मान का बाइट स्ट्रीम प्रतिनिधित्व उत्पन्न कर सकता है। सभी तत्वों के बाइट स्ट्रीम प्रतिनिधित्व को उत्पन्न करने के लिए, कॉलबैक फ़ंक्शन के रूप में array_map () फ़ंक्शन के अंदर क्रमबद्ध () फ़ंक्शन को कॉल करें। परिणाम एक आयामी सरणी होगा चाहे कितने स्तरों पर बहुआयामी सरणी हो।

चरण 2: मूल्यों को अद्वितीय बनाएं

इस एक आयामी सरणी को विशिष्ट बनाने के लिए, array_unique () फ़ंक्शन का उपयोग करें।

चरण 3: इसे बहुआयामी सरणी में वापस लाएं

हालांकि सरणी अब अद्वितीय है, मान बाइट स्ट्रीम प्रतिनिधित्व की तरह दिखता है। इसे वापस बहुआयामी सरणी में वापस लाने के लिए, unserialize () फ़ंक्शन का उपयोग करें।

$input = array_map("unserialize", array_unique(array_map("serialize", $input)));

इस सब के लिए फिर से धन्यवाद।


0

क्रमबद्ध और अद्वितीय के लिए एक विकल्प

$test = [
    ['abc','def'],
    ['ghi','jkl'],
    ['mno','pql'],
    ['abc','def'],
    ['ghi','jkl'],
    ['mno','pql'],
];

$result = array_reduce(
    $test,
    function($carry,$item){
        if(!in_array($item,$carry)) {
            array_push($carry,$item);
        }
        return $carry;
    },
    []
);

var_dump($result);

/*
 php unique.php
array(3) {
    [0] =>
        array(2) {
            [0] =>
                string(3) "abc"
            [1] =>
                string(3) "def"
        }
    [1] =>
        array(2) {
            [0] =>
                string(3) "ghi"
            [1] =>
                string(3) "jkl"
        }
    [2] =>
        array(2) {
              [0] =>
                  string(3) "mno"
              [1] =>
                  string(3) "pql"
        }
}

* /


0

यदि आपके पास इस तरह से एक सरणी है

data = array
(
[0] => array
(
    [subject] => a
    [object] => c
),
[1] => array
(
    [subject] => b
    [object] => d
),
[2] => array
(
    [subject] => d
    [object] => b
),
[3] => array
(
    [subject] => d
    [object] => c
),
[4] => array
(
    [subject] => c
    [object] => a
),
[5] => array
(
    [subject] => c
    [object] => d
)
)

और आप इस तरह से एरेज़ प्राप्त करना चाहते हैं:

data = array
(
[0] => array
(
    [subject] => a
    [object] => c
),
[1] => array
(
    [subject] => b
    [object] => d
),
[2] => array
(
    [subject] => d
    [object] => c
)
)

या

data = array
(
[0] => array
(
    [subject] => d
    [object] => b
),
[1] => array
(
    [subject] => c
    [object] => a
),
[2] => array
(
    [subject] => c
    [object] => d
)
)

निम्नलिखित कोड मदद कर सकता है

    $data1 = array();
    $data1 = $data;
    for($q=0;$q<count($data);$q++)
    {
            for($p=0;$p<count($data1);$p++)
            {
                    if (($data[$q]["subject"] == $data1[$p]["object"]) && ($data[$q]["object"] == $data1[$p]["subject"]))
                    {
                            $data1[$p]["subject"] = $data[$q]["subject"];
                            $data1[$p]["object"] = $data[$q]["object"];
                    }
            }
    }
    $data1 = array_values(array_map("unserialize", array_unique(array_map("serialize", $data1))));
    $data = $data1;

0

मैंने इस समस्या को बहुत सोचा है और निर्धारित किया है कि इष्टतम समाधान को दो नियमों का पालन करना चाहिए।

  1. स्केलेबिलिटी के लिए, जगह में सरणी को संशोधित करें; नए सरणी में कोई प्रतिलिपि नहीं
  2. प्रदर्शन के लिए, प्रत्येक तुलना केवल एक बार की जानी चाहिए

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

$count_array = count($input);
for ($i = 0; $i < $count_array; $i++) {
    if (isset($input[$i])) {
        for ($j = $i+1; $j < $count_array; $j++) {
            if (isset($input[$j])) {
                //this is where you do your comparison for dupes
                if ($input[$i]['checksum'] == $input[$j]['checksum']) {
                    unset($input[$j]);
                }
            }
        }
    }
}

एकमात्र दोष यह है कि जब पुनरावृत्ति पूरी हो जाती है तो चाबियाँ क्रम में नहीं होती हैं। यह एक समस्या नहीं है यदि आप बाद में केवल फॉर्च लूप्स का उपयोग कर रहे हैं, लेकिन यदि आपको लूप के लिए उपयोग करने की आवश्यकता है, तो आप $input = array_values($input);कुंजियों को फिर से शुरू करने के लिए ऊपर रख सकते हैं ।


0

मेरे उत्तर को जोड़ते हुए उत्तर के आधार पर सही है। छोटे कोड सिर्फ सूचकांकों को रीसेट करने के लिए जोड़े गए-

$input = array_values(array_map("unserialize", array_unique(array_map("serialize", $inputArray))));
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.