Reputation: 3804
How to filter an array to give unique elements according to one or more columns. Example:
array(
array('name'=>'toto', 'type'=>'1', 'type2'=> '2')
array('name'=>'tata', 'type'=>'1', 'type2'=> '3')
array('name'=>'titi', 'type'=>'1', 'type2'=> '2')
array('name'=>'tutu', 'type'=>'2', 'type2'=> '4')
array('name'=>'tete', 'type'=>'3', 'type2'=> '2')
)
If we choose type and type2 as the unique column. The result of the algorithm should gives
array(
array('name'=>'toto', 'type'=>'1', 'type2'=> '2')
array('name'=>'tata', 'type'=>'1', 'type2'=> '3')
array('name'=>'tutu', 'type'=>'2', 'type2'=> '4')
array('name'=>'tete', 'type'=>'3', 'type2'=> '2')
)
I can think of an algorithm by hashing the type concatenate with type2, store in a table and using isset to find the existence. But I'm not sure that's the best algorithm.
Upvotes: 4
Views: 4322
Reputation: 141
What about this way?
Result array is not the same as that of the author. But still valid for the condition:
...filter an array to give unique elements according to one or more columns.
<?php
declare(strict_types=1);
$input = [
['name' => 'toto', 'type' => '1', 'type2' => '2'],
['name' => 'tata', 'type' => '1', 'type2' => '3'],
['name' => 'titi', 'type' => '1', 'type2' => '2'],
['name' => 'tutu', 'type' => '2', 'type2' => '4'],
['name' => 'tete', 'type' => '3', 'type2' => '2'],
];
$keys = array_map(
static fn(string $key, string $value) => "$key:$value",
array_column($input, 'type'), array_column($input, 'type2'));
$result = array_values(array_combine($keys, array_values($input)));
$expect = [
['name' => 'titi', 'type' => '1', 'type2' => '2'],
['name' => 'tata', 'type' => '1', 'type2' => '3'],
['name' => 'tutu', 'type' => '2', 'type2' => '4'],
['name' => 'tete', 'type' => '3', 'type2' => '2'],
];
assert($result === $expect); // true
Upvotes: 0
Reputation: 95101
All you need is
$data = array(
array('name'=>'toto', 'type'=>'1', 'type2'=> '2'),
array('name'=>'tata', 'type'=>'1', 'type2'=> '3'),
array('name'=>'titi', 'type'=>'1', 'type2'=> '2'),
array('name'=>'tutu', 'type'=>'2', 'type2'=> '4'),
array('name'=>'tete', 'type'=>'3', 'type2'=> '2')
);
$tmp = array();
foreach($data as $v) {
$id = $v['type'] . "|" . $v['type2'];
isset($tmp[$id]) or $tmp[$id] = $v;
}
print_r(array_values($tmp));
Upvotes: 2
Reputation: 5457
Updated to support key combinations
<?php
$array=array(
array('name'=>'toto', 'type'=>'1', 'type2'=> '2'),
array('name'=>'tata', 'type'=>'1', 'type2'=> '3'),
array('name'=>'titi', 'type'=>'1', 'type2'=> '2'),
array('name'=>'tutu', 'type'=>'2', 'type2'=> '4'),
);
function filter($key,$array){
$filtered=array();
$used=array();
foreach ($array as $e){
$v=array();
foreach ($key as $k) $v[]=$e[$k];
if (!in_array($v,$used)){
$used[]=$v;
$filtered[]=$e;
}
}
return $filtered;
}
$filtered=filter(array('type2','type'),$array);
Upvotes: 1
Reputation: 522042
$keys = array('type', 'type2');
$filtered = array();
foreach ($array as $elem) {
$compKey = join('|', array_intersect_key($elem, array_flip($keys)));
$filtered[$compKey] = $elem;
}
// optionally: $filtered = array_values($filtered);
Upvotes: 2
Reputation: 1632
$arr = array(
array('name'=>'toto', 'type'=>'1', 'type2'=> '2'),
array('name'=>'tata', 'type'=>'1', 'type2'=> '3'),
array('name'=>'titi', 'type'=>'1', 'type2'=> '2'),
array('name'=>'tutu', 'type'=>'2', 'type2'=> '4')
);
$filtered = array(); // resulting array
$combinations = array(); // combinations of 'type' and 'type2' values
foreach ( $arr as $elem ) {
$comb = array($elem['type'], $elem['type2']);
if ( !in_array($comb, $combinations) ) { // new combination
$combinations[] = $comb;
$filtered[] = $elem;
}
}
Upvotes: 2