I was wondering what is the best way to eliminate duplicates within an array? Currently I'm running through a foreach loop to actually get this array, is there a way to say, if id already exists, don't insert into array?
foreach($categories2Sugg as $Category2Sugg)
{
$category_stringArray2Sugg[] = array("id"=>$Category2Sugg->id,"name"=>$Category2Sugg->name,"pluralName"=>$Category2Sugg->pluralName,"shortName"=>$Category2Sugg->shortName);
}
Array
(
[0] => Array
(
[id] => 4bf58dd8d48988d16c941735
[name] => Burger Joint
[pluralName] => Burger Joints
[shortName] => Burgers
)
[1] => Array
(
[id] => 4bf58dd8d48988d16c941735
[name] => Burger Joint
[pluralName] => Burger Joints
[shortName] => Burgers
)
[2] => Array
(
[id] => 4bf58dd8d48988d16c941735
[name] => Burger Joint
[pluralName] => Burger Joints
[shortName] => Burgers
)
[3] => Array
(
[id] => 4bf58dd8d48988d14e941735
[name] => American Restaurant
[pluralName] => American Restaurants
[shortName] => American
)
)
Or maybe its easier to do another function if this array already exists, just delete some values to output a new array?
Thanks!
Try array_unique php function that will help.
Also Try
$unique = array_map('unserialize', array_unique(array_map('serialize', $array)));
echo "<pre>";
print_r($unique);
echo "</pre>";
Above code is tested.
Complete Tested Code
<?php
$array = array
(
'0' => array
(
'id' => '4bf58dd8d48988d16c941735',
'name' => 'Burger Joint',
'pluralName' => 'Burger Joints',
'shortName' => 'Burgers'
),
'1' => array
(
'id' => '4bf58dd8d48988d16c941735',
'name' => 'Burger Joint',
'pluralName' => 'Burger Joints',
'shortName' => 'Burgers'
),
'2' => array
(
'id' => '4bf58dd8d48988d16c941735',
'name' => 'Burger Joint',
'pluralName' => 'Burger Joints',
'shortName' => 'Burgers'
),
'3' => array
(
'id' => '4bf58dd8d48988d14e941735',
'name' => 'American Restaurant',
'pluralName' => 'American Restaurants',
'shortName' => 'American'
)
);
$unique = array_map('unserialize', array_unique(array_map('serialize', $array)));
echo "<pre>";
print_r($unique);
?>
Cheers.
Related
I have an array with fields:
$products = array(
[0] => array('name' => 'product_one', 'category' => 'category_one', employee => '3234'),
[1] => array('name' => 'product_two', 'category' => 'category_two', employee => '5421'),
[2] => array('name' => 'product_three', 'category' => 'category_one', employee => '3234'),
[3] => array('name' => 'product_one', 'category' => 'category_one', employee => '2153'),
[4] => array('name' => 'product_one', 'category' => 'category_two', employee => '6312')
)
Now, in this case, employee field is not important, but the combination of product/category is unique.
Wanted result:
$products = array(
[0] => array('name' => 'product_one', 'category' => 'category_one', employee => '3234'),
[1] => array('name' => 'product_two', 'category' => 'category_two', employee => '5421'),
[2] => array('name' => 'product_three', 'category' => 'category_one', employee => '3234'),
[4] => array('name' => 'product_one', 'category' => 'category_two', employee => '6312')
)
Any idea what is the best way to do this? On production, I have more than 30.000 elements and usually around 10 duplicates. Also in real database, I have 12 fields and a combination of 4 of them needs to be unique).
If you don't mind which of the duplicates you keep, it's probably simplest to iterate over the loop, making a new array with keys which are a combination of the required unique values (I've used a separator of ## in this code, you can use anything that cannot occur in the values). This way duplicates will be automatically removed as an array cannot have identical keys. Once the loop is done the output array can be re-indexed numerically using array_values:
$output = array();
foreach ($products as $p) {
$output["{$p['name']}##{$p['category']}"] = $p;
}
$output = array_values($output);
print_r($output);
Output (for your sample data):
Array
(
[0] => Array
(
[name] => product_one
[category] => category_one
[employee] => 2153
)
[1] => Array
(
[name] => product_two
[category] => category_two
[employee] => 5421
)
[2] => Array
(
[name] => product_three
[category] => category_one
[employee] => 3234
)
[3] => Array
(
[name] => product_one
[category] => category_two
[employee] => 6312
)
)
Demo on 3v4l.org
I have an array of objects for example:
Array
(
[0] => Array
(
[Id] => 1
[Name] => Toy Car
[Category] => Toys
[Price] => 2.99
[OnSale] => false
)
...
)
But I'd like them to be grouped by Category, then by OnSale.
So far I have been able to group by category using:
$result = array();
foreach ($data as $element) {
$result[$element['Category']][] = $element;
}
But I am unsure how to nest another foreach or recursively group them once they have been grouped by Category. Any help is appreciated!
Do you mean:
$result = array();
foreach ($data as $element) {
$result[$element['Category']][$element['OnSale']][] = $element;
}
EDIT: Sorry, bit of a problem with all the [ and ]...
You're close! You just need to add the second key you want to group by.
$byCategoryAndSale = [];
foreach ($inventory as $item) {
$byCategoryAndSale[$item['Category']][$item['OnSale']][] = $item;
}
Note Using a boolean value as an array key will equate to 1's and 0's which can get pretty confusing.
Here's a full example:
<?php
$inventory = [
[
'Id' => 1,
'Name' => 'Toy Car',
'Category' => 'Toys',
'Price' => 2.99,
'OnSale' => false
],
[
'Id' => 2,
'Name' => 'Another Toy',
'Category' => 'Toys',
'Price' => 1.99,
'OnSale' => false
],
[
'Id' => 3,
'Name' => 'Hamburger',
'Category' => 'Not Toys',
'Price' => 5.99,
'OnSale' => false
],
[
'Id' => 4,
'Name' => 'Last Toy',
'Category' => 'Toys',
'Price' => 50.99,
'OnSale' => true
]
];
$byCategoryAndSale = [];
foreach ($inventory as $item) {
$byCategoryAndSale[$item['Category']][$item['OnSale']][] = $item;
}
print_r($byCategoryAndSale);
?>
Which yields:
PS C:\> php test.php
(
[Toys] => Array
(
[0] => Array
(
[0] => Array
(
[Id] => 1
[Name] => Toy Car
[Category] => Toys
[Price] => 2.99
[OnSale] =>
)
[1] => Array
(
[Id] => 2
[Name] => Another Toy
[Category] => Toys
[Price] => 1.99
[OnSale] =>
)
)
[1] => Array
(
[0] => Array
(
[Id] => 4
[Name] => Last Toy
[Category] => Toys
[Price] => 50.99
[OnSale] => 1
)
)
)
[Not Toys] => Array
(
[0] => Array
(
[0] => Array
(
[Id] => 3
[Name] => Hamburger
[Category] => Not Toys
[Price] => 5.99
[OnSale] =>
)
)
)
)
I have an associative multi dimensional array as below
$data = array();
$data = Array (
[0] => Array ( [class] => 1styear [branch] => IT [Exam] => SEM1 [student name] => Alex [Bio] => Good Boy )
[1] => Array ( [class] => 2ndyear [branch] => Finance [Exam] => SEM1 [student name] => Mark [Bio] => Intelligent )
[2] => Array ( [class] => 2ndyear [branch] => IT [Exam] => SEM1 [student name] => Shaun [Bio] => Football Player )
[3] => Array ( [class] => 1styear [branch] => Finance [Exam] => SEM2 [student name] => Mike [Bio] => Sport Player )
[4] => Array ( [class] => 1styear [branch] => IT [Exam] => SEM2 [student name] => Martin [Bio] => Smart )
[5] => Array ( [class] => 1styear [branch] => IT [Exam] => SEM1 [student name] => Philip [Bio] => Programmer )
)
I need to create new array based on similar element from above array. means I have to create array group. for e.g class element has repetitive 1styear and 2ndyear value. so it shouls create array of unique element. then again class is parent array and inside class array there should be branch based array and inside brance Exam array and inside Exam array there should be associative array of student name and bio.
so basically array should look like this
array(
"1styear" => array(
"IT" => array(
"SEM1" => array(
array(
"student name" => "Alex",
"Bio" => "Good Boy"
),
array(
"student name" => "Philip",
"Bio" => "Programmer"
)
),
"SEM2" => array(
array(
"student name" => "Martin",
"Bio" => "Smart"
)
)
)
),
"2ndyear" => array(
"Finance" => array(
"SEM1" => array(
array(
"student name" => "Mark",
"Bio" => "Intelligent"
)
),
"SEM2" => array(
array(
"student name" => "Mike",
"Bio" => "Sport Player"
)
)
)
)
);
To make group based on class i did like below which is working fine but how to create array inside that
$classgroup = array();
foreach($data as $inarray){
$classgroup[$inarray['class']][] = $inarray;
}
$classarray = array();
foreach($classgroup as $key => $value){
echo $key; // output is 1styear and secondyear
create array like above
}
---------------------------------EDIT----------------------------------
from the below loop
foreach($data as $array){
$grouped[$array["class"]][$array["branch"]][$array["Exam"]][]=array("student name"=>$array["student name"],"Bio"=>$array["Bio"]);
}
i got expected o/p
but if i need another o/p like this
expected o/p
array(
'1styear' =>
array (
0 =>
array(
'Exam' => 'SEM1',
'branch' =>
array (
0 => 'IT'
),
),
1 =>
array(
'Exam' => 'SEM2',
'branch' =>
array (
0 => 'IT'
),
),
),
'2ndyear' =>
array (
0 =>
array(
'Exam' => 'SEM1',
'branch' =>
array (
0 => 'Finance',
),
),
1 =>
array(
'Exam' => 'SEM2',
'branch' =>
array (
0 => 'Finance'
),
)
),
)
i tried following loop but not getting o/p as expected
foreach($data as $array){
$grouped[$array["class"]][]=array("Exam"=>$array["Exam"],"branch"=>$array["branch"]);
}
A one-liner in a loop!
foreach($data as $array){
$grouped[$array["class"]][$array["branch"]][$array["Exam"]][]=array("student name"=>$array["student name"],"Bio"=>$array["Bio"]);
}
$grouped produces:
Array(
[1styear] => Array(
[IT] => Array(
[SEM1] => array(
[0] => array(
[student name] => Alex,
[Bio] => Good Boy
),
[1] => array(
[student name] => Philip,
[Bio] => Programmer
)
),
[SEM2] => array(
[0] => array(
[student name] => Martin,
[Bio] => Smart
)
)
),
[Finance] => array(
[SEM2] => array(
[0] => array(
[student name] => Mike,
[Bio] => Sport Player
)
)
)
),
[2ndyear] => array(
[Finance] => array(
[SEM1] => array(
[0] => array(
[student name] => Mark,
[Bio] => Intelligent
)
)
),
[IT] => array(
[SEM1] => array(
[0] => array(
[student name] => Shaun,
[Bio] => Football Player
)
)
)
)
)
Your follow up case, was MUCH more fun/challenging. I had to knock the dust off of some functions I don't play with very often. Check this out:
<?php
$data = array (
array ( "class"=>"1styear","branch"=>"IT","Exam"=>"SEM1","student name"=>"Alex","Bio"=>"Good Boy"),
array ( "class"=>"2ndyear","branch"=>"Finance","Exam"=>"SEM1","student name"=>"Mark","Bio"=>"Intelligent" ),
array ( "class"=>"2ndyear", "branch"=>"IT","Exam"=>"SEM1","student name"=>"Shaun","Bio"=>"Football Player" ),
array ( "class"=>"1styear","branch"=>"Finance","Exam"=>"SEM2","student name"=>"Mike","Bio"=>"Sport Player" ),
array ( "class"=>"1styear","branch"=>"IT","Exam"=>"SEM2","student name"=>"Martin","Bio"=>"Smart"),
array ( "class"=>"1styear","branch"=>"IT","Exam"=>"SEM1","student name"=>"Philip","Bio"=>"Programmer" )
);
$class_keys=array_unique(array_column($data,"class")); // create array of unique class values
$Exam_keys=array_unique(array_column($data,"Exam")); // create array of unique Exam values
foreach($class_keys as $class_key){
$i=0; // "class" subarray index
foreach($Exam_keys as $Exam_key){
$q=array("class"=>$class_key,"Exam"=>$Exam_key); // this array can have 1 or more pairs
// create an array only of rows where $q's key-value pairs exist
$qualifying_array=array_filter(
$data,
function($val)use($q){
if(count(array_intersect_assoc($val,$q))==count($q)){ // total pairs found = total pairs sought
return $val;
}
},
ARRAY_FILTER_USE_BOTH
);
foreach($qualifying_array as $qa){ // push appropriate values into array
$grouped2[$class_key][$i]["Exam"]=$qa["Exam"];
$grouped2[$class_key][$i]["branch"][]=$qa["branch"];
}
if(isset($grouped2[$class_key][$i]["branch"])){ // ensure no duplicate values in "branch" subarray
$grouped2[$class_key][$i]["branch"]=array_unique($grouped2[$class_key][$i]["branch"]);
}
++$i; // increment the index for each "class" subarray
}
}
echo "<pre>";
print_r($grouped2);
echo "</pre>";
The output isn't identical to what you requested, but I think you were just showing what it should look like generally. If this isn't quite right, let me know.
array(
[1styear]=>array(
[0]=>array(
[Exam]=>SEM1
[branch]=>array(
[0]=>IT
)
),
[1]=>array(
[Exam]=>SEM2
[branch]=>array(
[0]=>Finance,
[1]=>IT
)
)
),
[2ndyear]=>array(
[0]=>array(
[Exam]=>SEM1
[branch]=>array(
[0]=>Finance,
[1]=>IT
)
)
)
)
Maybe something like this (not tested)?
$newData = [];
foreach ($data as $row) {
$student = [
'student name' => $row['student name'],
'Bio' => $row['Bio']
];
$newData[$row['class']][$row['branch']][$row['exam']][] = $student;
}
I have 2 multidimensional arrays that I am working with:
$arr1 =
Array
([type] => characters
[version] => 5.6.7.8
[data] => Array
([Char1] => Array
([id] => 1
[name] =>Char1
[title] =>Example
[tags] => Array
([0] => DPS
[1] => Support))
[Char2] => Array
([id] => 2
[name] =>Char2
[title] =>Example
[tags] => Array
([0] => Tank
[1] => N/A)
)
)
etc...
$arr2=
Array
([games] => Array
([gameId] => 123
[gameType => Match
[char_id] => 1
[stats] => Array
([damage] => 55555
[kills] => 5)
)
([gameId] => 157
[gameType => Match
[char_id] => 2
[stats] => Array
([damage] => 12642
[kills] => 9)
)
etc...
Basically, I need almost all the data in $arr2... but only the Char name from $arr1. How could I merge or add the $arr1['name'] key=>value into $arr2 where $arr1['id'] is equal to $arr2['char_id'] as the "id" field of each array is the same number.
I've attempted using array_merge and array_replace, but I haven't come up with any working solutions. This is also all data that I am receiving from a 3rd party, so I have no control on initial array setup.
Thanks for any help or suggestions!
Actually, this is quite straighforward. (I don't think there a built-in function that does this.)
Loop $arr2 and under it loop also $arr1. While under loop, just add a condition that if both ID's match, add that particular name to $arr2. (And use some referencing & on $arr2)
Consider this example:
// your data
$arr1 = array(
'type' => 'characters',
'version' => '5.6.7.8',
'data' => array(
'Char1' => array(
'id' => 1,
'name' => 'Char1',
'title' => 'Example',
'tags' => array('DPS', 'Support'),
),
'Char2' => array(
'id' => 2,
'name' => 'Char2',
'title' => 'Example',
'tags' => array('Tank', 'N/A'),
),
),
);
$arr2 = array(
'games' => array(
array(
'gameId' => 123,
'gameType' => 'Match',
'char_id' => 1,
'stats' => array('damage' => 55555, 'kills' => 5),
),
array(
'gameId' => 157,
'gameType' => 'Match',
'char_id' => 2,
'stats' => array('damage' => 12642, 'kills' => 9),
),
),
);
foreach($arr2['games'] as &$value) {
$arr2_char_id = $value['char_id'];
// loop and check against the $arr1
foreach($arr1['data'] as $element) {
if($arr2_char_id == $element['id']) {
$value['name'] = $element['name'];
}
}
}
echo '<pre>';
print_r($arr2);
$arr2 should look now like this:
Array
(
[games] => Array
(
[0] => Array
(
[gameId] => 123
[gameType] => Match
[char_id] => 1
[stats] => Array
(
[damage] => 55555
[kills] => 5
)
[name] => Char1 // <-- name
)
[1] => Array
(
[gameId] => 157
[gameType] => Match
[char_id] => 2
[stats] => Array
(
[damage] => 12642
[kills] => 9
)
[name] => Char2 // <-- name
)
)
)
Iterate over $arr2 and add the data to it from the matching $arr1 array value:
$i = 0;
foreach($arr2['games'] as $arr2Game){
$id = $arr2Game['char_id'];
$arr2['games'][$i]['name'] = $arr1['data'][$id]['name'];
$i++;
}
Have not tested this code.
If I'm understanding you correctly, you want to add a name index to each of the arrays within the $arr2['games'] array.
foreach($arr2['games'] as $key => $innerArray)
{
$arr2['games'][$key]['name'] = $arr1['data']['Char'.$innerArray['char_id']]['name'];
}
I have to array and I want to merge this two array with a main key ( ID ) , and I would like to order alphabetically this NEW array ( the lastname field )
Array (
[0] =>
Array ( [id] => 172
[user_id] => 1217330
[behaviour_action_id] => 97
[state] => accepted
)
[1] =>
Array (
[id] => 173
[user_id] => 1217330
[behaviour_action_id] => 97
[state] => pending
) )
And this array
Array (
[1217330 ] =>
Array ( [firstname] => Philip
[lastname] => Audet
[birthdate] => 1995-07-17
[id] => 1217330
)
[232323] =>
Array ( [firstname] => Frédéric
[lastname] => Bouchard-Dubé
[birthdate] => 1995-07-17
[id] => 232323
)
And I would like to have this
[0] =>
Array ( [id] => 172
[user_id] => 1217330
[behaviour_action_id] => 97
[state] => accepted
[firstname] => Philip
[lastname] => Audet
)
[1] =>
Array (
[id] => 173
[user_id] => 1217330
[behaviour_action_id] => 97
[state] => pending
[firstname] => Philip
[lastname] => Audet
) )
I wont want to have the birthdate index for THIS array, I only want to get the firstname and the lastname from the second array. So I want to math the index USER_ID ( first_table) with ID (second table). I also want to order this new table alphabetically with the lastname (in my exemple, I don't need to sort it alphabetically, but I will need to do this )
Can some one can help me please ? Thx
Thx
This is doing what you are looking for. As your example is out of context you might need to take some different approaches, but I hope it will help you get the task done.
$behaviour = array(
array(
'id' => 172,
'user_id' => 1217330,
'behaviour_action_id' => 97,
'state' => 'accepted'
),
array(
'id' => 173,
'user_id' => 232323,
'behaviour_action_id' => 97,
'state' => 'pending'
),
);
$users = array(
1217330 => array(
'firstname' => 'Philip',
'lastname' => 'Audet',
'birthdate' => '1995-07-17',
'id' => 1217330
),
232323 => array(
'firstname' => 'Frédéric',
'lastname' => 'Bouchard-Dubé',
'birthdate' => '1995-07-17',
'id' => 232323
),
);
//we will collect the data in a new array
$combined = array();
//now we loop through all behaviours
foreach($behaviour as $key => $behaviourData){
//we look up the data which belongs to the user of this behaviour
$wantedUserData = $users[$behaviourData['user_id']];
//birthdate is unwanted
unset($wantedUserData['birthdate']);
//merge data
$combined[] = array_merge($behaviourData, $wantedUserData);
}
//order array
usort($combined,'cmp');
//voilà!
var_dump($combined);
//Comparison function used in usort above
function cmp($a, $b){
if ($a['lastname'] == $b['lastname']){
return 0;
}
return ($a['lastname'] < $b['lastname']) ? -1 : 1;
}
$arr1 = array (
array("id"=>172, "user_id"=>1217330, "behaviour_action_id"=>97, "state"=>"accepted"),
array("id"=>173, "user_id"=>1217330, "behaviour_action_id"=>97, "state"=>"pending")
);
$arr2 = array(
"1217330" => array(
"firstname" => "Philip",
"lastname" => "Audet",
"birthdate" => "1995-07-17",
"id" => 1217330
),
"232323" => array (
"firstname" => "Frédéric",
"lastname" => "Bouchard-Dubé",
"birthdate" => "1995-07-17",
"id" => 232323
)
);
foreach($arr1 as $arr) {
$extra = $arr2[$arr["user_id"]];
unset($extra["birthdate"]);
$newarray[] = array_merge($extra, $arr);
}
print_r($newarray);
this one? (assuming $arr1 and $arr2 the given arrays)
$arr3 = array();
foreach($arr1 as $key=>$val) {
$arr3[$key] = $val;
$arr3[$key]["firstname"] = $arr2[$val["user_id"]]["firstname"];
$arr3[$key]["lastname"] = $arr2[$val["user_id"]]["lastname"];
}
echo "<pre>";
print_r($arr3);
echo "</pre>";
Well, I don't want to give a cooked-up code but this algorithm will do the job:
1) Loop through first array and create another array with user_id as key. like
$new_array[$array['user_id']] = array($array['id'], $array['state']...);
2) Loop through second array and unset() the key birthdate.
3) Use array_merge_recursive() and merge the two arrays.