পিএইচপি-তে একটি বহুমাত্রিক অ্যারে থেকে সদৃশ মানগুলি কীভাবে সরাবেন


306

আমি পিএইচপি-তে একটি বহুমাত্রিক অ্যারে থেকে সদৃশ মানগুলি কীভাবে সরিয়ে ফেলতে পারি?

উদাহরণ অ্যারে:

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
আনসিরিয়ালাইজের কারণে এটি ধীর এবং ধীরে ধীরে বড় অ্যারেটি আরও জটিল এবং জটিল। আমি অ্যারে_ইন্টারসেকট_কি ব্যবহার করার একটি কারণ রয়েছে (এই উত্তরটির অর্ধ বছর আগে)
ওআইএস

11
@ ওআইএস এটি ঠিক পরীক্ষা করেছে, টাইপও করেছে তবে এটি কাজ করে .. ধন্যবাদ ডুড !: _ নো ডুপ্লিকেটস = অ্যারে_ইন্টারকেট_কি ($ অ্যারে, অ্যারে_উনিক (অ্যারে_ম্যাপ ('সিরিয়ালাইজ', $ অ্যারে))));
ট্র্যাভোরকাভানহো

3
আপনি যদি সূচককে অবিচ্ছিন্ন রাখতে চান তবে অ্যারে_ভ্যালুগুলি যেমন $ ইনপুট = অ্যারে_ভ্যালু (অ্যারে_ম্যাপ ("আনসিরিয়ালাইজ"), অ্যারে_উনিক (অ্যারে_ম্যাপ ("সিরিয়ালাইজ", $ ইনপুট)))) ব্যবহার করুন);
lbsweek

4
আজকাল আপনি সম্ভবত পিএইচপি সিরিয়ালাইজের পরিবর্তে json_encode এবং json_decode বেছে নেবেন। প্রদত্ত মানগুলির জন্য সুবিধাগুলি থাকা উচিত এবং আপনি পিএইচপি সিরিয়ালাইজেশন বিশদটি চালান না যা জাহাজগুলি সিরিয়ালাইজ / আনসিরিয়ালাইজ করে এবং সম্ভবত অযাচিত হয়।
হ্যাক্রে

2
serialize(array('a' => '1', 'b' => '1'))থেকে আলাদা যে সাবধান serialize(array('b' => '1', 'a' => '1'))। এই বিকল্পটি হিসাবে ব্যবহার অ্যারে জন্য ব্যর্থ হবে setsবা (hash)maps
Andras Gyomrey

240

৫.২.৯ থেকে আপনি array_unique()যদি SORT_REGULARপতাকাটি ব্যবহার করেন তবে আপনি ব্যবহার করতে পারবেন :

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
@ স্টেফান আপনি ঠিক বলেছেন; এটি সঠিক ফলাফল দেবে বলে মনে হচ্ছে না তবে এটি সম্ভবত একটি বাগ কারণ এটি পিএইচপি 7 = /
জ্যাক

4
এটি আমার ক্ষেত্রেও কাজ করে বলে মনে হচ্ছে তবে অ্যারে_উনিক () ডকমে অন্য কেউ এই নোটটি নিয়ে বিরক্ত? php.net/manual/en/…
হিক্স

2
@ জ্যাক আপনি ঠিক বলেছেন এটি পিএইচপি 5.6.23 হিসাবে একটি বাগ: eval.in/645675 তবে পিএইচপি 7.0.8 হিসাবে ঠিক করা হয়েছে: eval.in/645676
জ্যাক মরিস

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/…
ওআইএস

দুর্দান্ত ফাংশন! এবং যদি আপনি অবজেক্টগুলির সাথে লেনদেন করছেন: যদি (! isset ($ অ্যারে -> $ 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

ব্যবহারকারী অ্যারে_উনিকের মন্তব্য () ডকুমেন্টেশনে অনেকগুলি সমাধান রয়েছে। তাদের মধ্যে একটি এখানে:

kenrbnsn at rbnsn dot com
27-Sep-2005 12:09

তবুও বহু-বিঘ্নিত অ্যারেগুলির জন্য অন্য আরে_উইনিক। আমি এটি কেবল দ্বি-বিকেন্দ্রিত অ্যারে পরীক্ষা করেছি, তবে এটি সম্ভবত আরও সাধারণের জন্য, বা পুনরাবৃত্তি ব্যবহারের জন্য তৈরি করা যেতে পারে।

এই ফাংশনটি কাজটি করতে সিরিয়ালাইজ, অ্যারে_উনিক এবং আনসিরিয়াল ফাংশন ব্যবহার করে।


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"
স্টিভান্স 26


4

দ্বিতীয় পরামিতি হিসাবে কেবল SORT_REGULAR বিকল্পটি ব্যবহার করুন।

$uniqueArray = array_unique($array, SORT_REGULAR);

1
SORT_REGULAR শুধুমাত্র পিএইচপি 7 কাজ করে কারণ পিএইচপি 5 একটি বাগ আছে (যদিও @ r3wt ডকুমেন্টেশন অনুযায়ী সঠিক), একটি runnable উদাহরণস্বরূপ উত্তর আমার মন্তব্য দেখতে stackoverflow.com/questions/307674/...
জ্যাক মরিস

আপনি এটি যুক্ত করবেন কেন? : এটা এই উত্তর, যা এক বছর ধরে পুলিশের চেয়ে পুরোনো হিসাবে একই stackoverflow.com/a/18373723/870729
random_user_name

3

আপনার যদি নির্দিষ্ট কীগুলিতে যেমন একটি মাইসকিলি আইডিতে নকলগুলি অপসারণের প্রয়োজন হয় তবে এখানে একটি সাধারণ ফানসিটন's

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));
কীবোর্ডসামেশার

@ কিবোর্ডমাশার আপনার ইনপুট জন্য আপনাকে ধন্যবাদ। আমি পরিবর্তনগুলি করেছি এবং এখন এটি কার্যকর হয়। :)
অনুজ

1

প্রচুর ব্যক্তি আমাকে কীভাবে অনন্য বহুমাত্রিক অ্যারে করবেন তা জিজ্ঞাসা করেছিলেন। আমি আপনার মন্তব্য থেকে রেফারেন্স নিয়েছি এবং এটি আমাকে সাহায্য করে।

সবার আগে, আপনার সমাধানের জন্য @ জেরোমেগামেজ @ ডেভেলারদের ধন্যবাদ। তবে যতবার আমি উত্তরটি দিয়েছি, তারা আমাকে জিজ্ঞাসা করেছিল যে এটি কীভাবে 'সিরিয়ালাইজ' এবং 'আনসিরিয়ালাইজেশন' কাজ করে। এজন্য আমি এর কারণটি আপনার সাথে ভাগ করে নিতে চাই যাতে এটি আরও লোককে এর পিছনে ধারণাটি বুঝতে সহায়তা করে।

আমি ব্যাখ্যা করছি যে আমরা কেন পদক্ষেপে 'সিরিয়ালাইজ' এবং 'আনসিরিয়ালাইজেশন' ব্যবহার করি:

পদক্ষেপ 1: বহুমাত্রিক অ্যারেটিকে এক-মাত্রিক অ্যারেতে রূপান্তর করুন

বহুমাত্রিক অ্যারেটিকে এক-মাত্রিক অ্যারেতে রূপান্তর করতে প্রথমে অ্যারের অভ্যন্তরে সমস্ত উপাদানগুলির (বর্ধিত অ্যারেগুলি সহ) বাইট স্ট্রিম উপস্থাপনা তৈরি করুন। সিরিয়ালাইজ () ফাংশন একটি মানের বাইট স্ট্রিম উপস্থাপনা তৈরি করতে পারে। সমস্ত উপাদানগুলির বাইট স্ট্রিম উপস্থাপনা উত্পন্ন করতে, অ্যারে_ম্যাপ () ফাংশনের ভিতরে সিরিয়ালাইজ () ফাংশনটিকে কলব্যাক ফাংশন হিসাবে কল করুন। বহুমাত্রিক অ্যারে কত স্তর রয়েছে তা নির্ধারণ করেই ফলাফলটি একটি মাত্রিক অ্যারে হবে।

পদক্ষেপ 2: মানগুলি অনন্য করুন

এই এক মাত্রিক অ্যারেটিকে অনন্য করতে, অ্যারে_উনিক () ফাংশনটি ব্যবহার করুন।

পদক্ষেপ 3: এটি বহুমাত্রিক অ্যারেতে ফিরিয়ে দিন

অ্যারেটি যদিও এখন অনন্য, মানগুলি বাইট স্ট্রিম উপস্থাপনের মতো দেখাচ্ছে। এটিকে আবার বহুমাত্রিক অ্যারেতে ফিরতে, আনসিরিয়ালাইজ () ফাংশনটি ব্যবহার করুন।

$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))));
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.