Make associative array of unique values from column containing arrays

108 Views Asked by At
Array
(
    [0] => Array
    (
        [id] => 21153
        [genre] => ["History","Drama", "Thriller"]
    )

    [1] => Array
    (
        [id] => 21152
        [genre] => ["ACTION"]
    )

    [2] => Array
    (
        [id] => 21151
        [genre] => ["ROMANTIC"]
    )

    [3] => Array
    (
        [id] => 21150
        [genre] => ["Drama"]
    )

)

I have with the above array and I want to convert that array to an unique array as mentioned below, and there should be any duplicate values.

Array(
    [History] => "History"
    [ACTION] => "ACTION"
    [ROMANTIC] => "ROMANTIC"
    [Drama] => "Drama"
    [Thriller]=>"Thriller"
)
5

There are 5 best solutions below

0
On
  1. Flatten the column of data.
  2. Assign keys from the values (this ensures uniqueness).

Code: (Demo)

$array = [
    ["id" => 21153, "genre" => ["History", "Drama", "Thriller"]],
    ["id" => 21152, "genre" => ["ACTION"]],
    ["id" => 21151, "genre" => ["ROMANTIC"]],
    ["id" => 21150, "genre" => ["Drama"]]         
];

$flat = array_merge(...array_column($array, 'genre'));
var_export(
    array_combine($flat, $flat)
);

Output:

array (
  'History' => 'History',
  'Drama' => 'Drama',
  'Thriller' => 'Thriller',
  'ACTION' => 'ACTION',
  'ROMANTIC' => 'ROMANTIC',
)
0
On

By doing the changes, I have fixed this,

$responseData = Array(
[0] => Array
    (
        [id] => 21153
        [genre] => ["History","Drama", "Thriller"]
    )

[1] => Array
    (
        [id] => 21152
        [genre] => ["ACTION"]
    )

[2] => Array
    (
        [id] => 21151
        [genre] => ["ROMANTIC"]
    )

[3] => Array
    (
        [id] => 21150
        [genre] => ["Drama"]
    )

       foreach ($responseData as $data){
       $strReplace = str_replace(array('[',']') , ''  ,  $data['genre']);
       $explodeData[] = explode(',', $strReplace);  
   }

And the output after exploding is :

$explodeData = Array

( [0] => Array ( [0] => "History" [1] => "Drama" [2] => "Thriller" )

[1] => Array
    (
        [0] => "ACTION"
    )

[2] => Array
    (
        [0] => "ROMANTIC"
    )

[3] => Array
    (
        [0] => "Drama"
    )

)

And finally by the foreach loop :

       foreach ($explodeData as $arr) {
        foreach ($arr as $genres) {
            if (!in_array($genres, $myArray)) {
                $myArray[$genres] = $genres;
            }
        }
    }

And finally the required output comes as below :

Array(
["History"] => "History"
["Drama"] => "Drama"
["Thriller"] => "Thriller"
["ACTION"] => "ACTION"
["ROMANTIC"] => "ROMANTIC"
)
0
On

I don't really get how the resulting array makes any sense, but here you are:
Loop through the array, loop through the genres and push items to a new array.

<?
$a = Array
(
    [
        "id" => 21153,
        "genre" => ["History","Drama", "Thriller"]
    ],

    [        
        "id" => 21152,
        "genre" => ["ACTION"]
    ]

);


$result = [];
foreach($a as $b) {
    foreach($b['genre'] as $genre) {
        $result[$genre] = $genre;  // don't need to check if it exists already, because we'll overwrite it anyway.
    }
}

echo "<pre>";
print_r($result);
echo "</pre>";

// output:
Array
(
    [History] => History
    [Drama] => Drama
    [Thriller] => Thriller
    [ACTION] => ACTION
)
0
On

It can be done by using foreach() loop and in_array() function like below

$myArray=array();
$array = array(
            array("id"=>21153,"genre"=>array("History","Drama", "Thriller")),
            array("id"=>21152,"genre"=>array("ACTION")),
            array("id"=>21151,"genre"=>array("ROMANTIC")),
            array("id"=>21150,"genre"=>array("Drama"))          
        );

foreach($array as $arr){    
    foreach($arr as $genres){
        if(is_array($genres)){
            foreach($genres as $elem){
                  if (!in_array($elem, $myArray))
                  {
                    $myArray[$elem]=$elem;
                  }
            }
        }
    }
}

print_r($myArray);
0
On

This is a function that resolves what you ask, though I'm not sure it is quite useful to have value and key being identical. I'm just looping over all genders and add only the ones I don't already have store in returning array. probably a bit dangerous with your code because it is case sensitive

function getGenders(array $rawValues) :array {
    $distinctGenders = [];
    foreach ($rawValues as $row) {
        foreach ($row["genre"] as $gender) {
            if (!in_array($gender, $distinctGenders)) {
                $distinctGenders[$gender] = $gender;
            }
        }
    }

    return $distinctGenders;
}