Remove duplicates from multi-dimensional array based on higher points - php

I'm racking my brains trying to think of a solution. I can find plenty of solutions to remove dupes from a 2d array but I need to remove dupes where a value is lower than the other. Here is the array:
Array
(
[basketball] => Array
(
[0] => stdClass Object
(
[id] => 2
[username] => Beans
[points] => 30
)
[1] => stdClass Object
(
[id] => 314
[username] => slights
[points] => 20
)
[2] => stdClass Object
(
[id] => 123
[username] => gibb54
[points] => 5
)
)
[soccer] => Array
(
[0] => stdClass Object
(
[id] => 2
[username] => Beans
[points] => 95
)
[1] => stdClass Object
(
[id] => 49
[username] => sans
[points] => 65
)
[2] => stdClass Object
(
[id] => 122
[username] => peano
[points] => 50
)
[3] => stdClass Object
(
[id] => 174
[username] => fordb
[points] => 30
)
[4] => stdClass Object
(
[id] => 112
[username] => danc
[points] => 30
)
)
)
As you may see, user ID 2, Beans is the first selection for both basketball and soccer. As they have more points for soccer, I need to remove their entry for basketball to make ID 314, slights the 0 value.
I would need to do this continually until no user be the 0 value for any of the primary array values twice.
I've tried various combinations of foreach solutions but I'm not getting anywhere. I thought a while loop would be more suitable but I don't know what condition to test for.
Any ideas please?!

I would loop through your data and create a dictionary where the keys are the user ids, and the values are the appropriate user objects with the sport appended. Then you can reconstruct your example data array structure by looping through this de-duped array using the sport data to determine where to put each user.
To create the de-duped array, use something like:
$deDupedData = array();
foreach ($data as $sport => $users) {
foreach ($users as $user) {
if (isset($deDupedData[$user->id])) {
if ($user->points > $deDupedData[$user->id]->points) {
$deDupedData[$user->id]->sport = $sport;
$deDupedData[$user->id]->points = $user->points;
}
} else {
$modifiedUser = $user;
$modifiedUser->sport = $sport;
$deDupedData[$user->id] = $modifiedUser;
}
}
}
// Now reconstruct your array...

Related

Getting out the value of a key in multidimentional array in php

In my php query I got this output:
{"projects":[{"id":127,"name":"efrat","status":{"id":10,"name":"development","label":"development"},"description":"","enabled":true,"view_state":{"id":10,"name":"public","label":"public"},"access_level":{"id":90,"name":"administrator","label":"administrator"},"custom_fields":[{"id":1,"name":"Customer email","type":"email","default_value":"","possible_values":"","valid_regexp":"","length_min":0,"length_max":50,"access_level_r":{"id":10,"name":"viewer","label":"viewer"},"access_level_rw":{"id":10,"name":"viewer","label":"viewer"},"display_report":true,"display_update":true,"display_resolved":true,"display_closed":true,"require_report":false,"require_update":false,"require_resolved":false,"require_closed":false}],"versions":[],"categories":[{"id":93,"name":"Monitor","project":{"id":0,"name":null}},{"id":31,"name":"Proactive","project":{"id":0,"name":null}},{"id":30,"name":"Project","project":{"id":0,"name":null}},{"id":29,"name":"Support","project":{"id":0,"name":null}}]}]}
after using 'json_decode' method on it, I get this:
"(
[projects] => Array
(
[0] => Array
(
[id] => 127
[name] => myprojectname
[status] => Array
(
[id] => 10
[name] => development
[label] => development
)
[description] =>
[enabled] => 1
[view_state] => Array
(
[id] => 10
[name] => public
[label] => public
)
[access_level] => Array
(
[id] => 90
[name] => administrator
[label] => administrator
)
[custom_fields] => Array
(
[0] => Array
(
[id] => 1
[name] => Customer email
[type] => email
[default_value] =>
[possible_values] =>
[valid_regexp] =>
[length_min] => 0
[length_max] => 50
[access_level_r] => Array
(
[id] => 10
[name] => viewer
[label] => viewer
)
[access_level_rw] => Array
(
[id] => 10
[name] => viewer
[label] => viewer
)
[display_report] => 1
[display_update] => 1
[display_resolved] => 1
[display_closed] => 1
[require_report] =>
[require_update] =>
[require_resolved] =>
[require_closed] =>
)
)
[versions] => Array
(
)
[categories] => Array
(
[0] => Array
(
[id] => 93
[name] => Monitor
[project] => Array
(
[id] => 0
[name] =>
)
)
[1] => Array
(
[id] => 31
[name] => Proactive
[project] => Array
(
[id] => 0
[name] =>
)
)
[2] => Array
(
[id] => 30
[name] => Project
[project] => Array
(
[id] => 0
[name] =>
)
)
[3] => Array
(
[id] => 29
[name] => Support
[project] => Array
(
[id] => 0
[name] =>
)
)
)
)
)
)"
In my PHP, how can I release the "name" object value (the result should be 'myprojectname') from this array? I've tried many foreach loops that got me nowhere.
Thank you,
It looks like you have one object, that when decoded actually only has one array item. So, in your case, ‘myprojectname’ may simply be “$projects[0][‘name’]”
If many array items, you could
foreach ($projects as $project) {
echo $project[‘name’];
}
EDIT: I took object provided and json_decoded it myself, it doesn't match the json_decoded item presented by OP -- the first image shows the code to var_dump 'name' OP desired, part of the code also below:
$decoded = json_decode($obj);
$projects = $decoded->projects;
$name = $projects[0]->name;
Your 'projects' contains an array ("projects":[{"id":127, ... }]). I assume that the 'projects'-array might contain multiple 'project'-objects like this?
{
"projects":
[
{
"id":127,
"name":"my-project"
},
{
"id":128,
"name":"my-other-project"
}
]
}
In that case you need the arrow notation to access the name property, for example:
foreach ($projects as $project_object) {
foreach ($project_object as $project) {
echo $project->name . '<br/>';
}
}
EDIT:
I took a minimal code example of the OP and got the expected result:
Can you add more details in your code snippets in your original question or provide us with a working example of your code?
There are some online PHP sandboxes that can help you with this. For example: I stripped out all code that does not seem related to your question and got the result you are looking for in two different ways:
http://sandbox.onlinephpfunctions.com/code/009c53671fd9545e4fcecfe4b0328974381ee2ce
It is also a good idea to sum up all the foreach loops that you already tried, so we can see if you were nearly there with your own solution. This way we can understand your question better and it prevents us from offering solutions that you already used.

Insert auto generated multidimensional array to database

I need to create a db function for multidimensional array. How deep the array currently dont know, bcoz they will come from xml file.
I have a sample array
Array
(
[employee] => Array
(
[0] => Array
(
[name] => Array
(
[lastname] => Kelly
[firstname] => Grace
)
[hiredate] => October 15, 2005
[projects] => Array
(
[project] => Array
(
[0] => Array
(
[product] => Printer
[id] => 111
[price] => $111.00
)
[1] => Array
(
[product] => Laptop
[id] => 222
[price] => $989.00
)
)
)
)
[1] => Array
(
[name] => Array
(
[lastname] => Grant
[firstname] => Cary
)
[hiredate] => October 20, 2005
[projects] => Array
(
[project] => Array
(
[0] => Array
(
[product] => Desktop
[id] => 333
[price] => $2995.00
)
[1] => Array
(
[product] => Scanner
[id] => 444
[price] => $200.00
)
)
)
)
[2] => Array
(
[name] => Array
(
[lastname] => Gable
[firstname] => Clark
)
[hiredate] => October 25, 2005
[projects] => Array
(
[project] => Array
(
[0] => Array
(
[product] => Keyboard
[id] => 555
[price] => $129.00
)
[1] => Array
(
[product] => Mouse
[id] => 666
[price] => $25.00
)
)
)
)
)
)
I need to enter these type of array to db and then retrieve them in a good non programmer readable format
I created 2 table... 1st for array key with array level field and another for key=value
I tried this
function array_Dump($array, $d=1){
if (is_array($array)){
foreach($array as $key=>$val){
for ($i=0;$i<$d;$i++){
$level=$i;
}
if (is_array($val)){
if (is_int($key)){
array_Dump($val, $d+1);
}else{
$query = "insert into xml_array (level, input) VALUES ('$level','$key')";
insert_sql($query);
array_Dump($val, $d+1);
}
} else {
$query = "insert into xml_data (array_id,level_id, array_key,array_value) VALUES ('$insert_id','$level','$key','$val')";
insert_sql($query);
}
}
}
}
Create a table like this:
attributes(id, parent_id, properties)
where id will be the primary key, parent_id will be the id of the parent record and properties will be a small json field with the atomic properties. This way you support any depth the XML may throw towards your direction.
As about non-programmer representation. For instance you could use a table (you can solve that with divs as well) which will contain a row for each element in the top level array. Such a row would contain separate columns for each property. When a property is an array, then the given cell will be a table of its own, which will be handled similarly as the first table. It is advisable to make the inner tables collapsible, so if one wants to see the main levels only, the user will not have to scroll for a long while.

php, compare arrays and append difference

I have these two arrays:
1:
Array
(
[0] => stdClass Object
(
[id] => 1
[name] => Type 1
[rate] => 100.00
)
[1] => stdClass Object
(
[id] => 2
[name] => Type 2
[rate] => 75.00
)
[2] => stdClass Object
(
[id] => 3
[name] => Type 3
[rate] => 50.00
)
[3] => stdClass Object
(
[id] => 4
[name] => Type 4
[rate] => 50.00
)
)
2:
Array
(
[0] => stdClass Object
(
[name] => Type 1
[rate] => 125
)
[1] => stdClass Object
(
[name] => Type 2
[rate] => 85
)
[2] => stdClass Object
(
[name] => Type 3
[rate] => 65
)
)
What I need to do is compare the two arrays, and append missing items from 1st array to the 2nd one. This will always be the case first array will have more items than the second one.
I have tried using something like:
$result = array_udiff($array1,$array2,
function ($obj_a, $obj_b) {
return $obj_a->name - $obj_b->name;
}
);
but it just returns an empty array
This?
<?php
$arr1 = array(
(object)array("id"=>1,"name"=>"type 1","rate"=>100.00),
(object)array("id"=>2,"name"=>"type 2","rate"=>75.00),
(object)array("id"=>3,"name"=>"type 3","rate"=>50.00),
(object)array("id"=>4,"name"=>"type 4","rate"=>50.00)
);
$arr2 = array(
(object)array("name"=>"type 1","rate"=>125),
(object)array("name"=>"type 2","rate"=>85),
(object)array("name"=>"type 3","rate"=>65)
);
for($i=0;$i<sizeof($arr1);$i++){
$count=0;
for($j=0;$j<sizeof($arr2);$j++){
if($arr1[$i]->name == $arr2[$j]->name){
$count++;
}
}
if($count==0){
array_push($arr2,(object)array("name"=>$arr1[$i]->name,"rate"=>$arr1[$i]->rate));
}
}
print_r($arr2);
?>
Doesn't need to be complicated, assuming that you allow the arrays to contain objects of the same type and structure. We don't have enough context given the question to understand whether there is a good reason you can't.
//$array1 original array
//$array2 target array
$array2 = array_merge($array1, $array2);

How can I merge or search an object?

Here's my issue:
I have an object filled with arrays that look like this.
[376339] => Array
(
[0] => 1f422730-f54b-4e4d-9289-10258ce74446
[1] => 60dc4646-06ce-44d0-abe9-ee371847f4df
)
I need to search another object to find objects with the matching IDs, like below. Is there a way of doing this without a foreach? There are SEVERAL and I would like to not have to loop over the entire object every time.
stdClass Object
(
[id] => 1f422730-f54b-4e4d-9289-10258ce74446
[percentage] => 32
[destinations] => Array
(
[0] => stdClass Object
(
[id] => 59826
[destination_id] => 59826
[type] => Destination
[dequeue] =>
[value] => xxxxxxxxxxx
)
)
)
stdClass Object
(
[id] => 60dc4646-06ce-44d0-abe9-ee371847f4df
[percentage] => 68
[destinations] => Array
(
[0] => stdClass Object
(
[id] => 60046
[destination_id] => 60046
[type] => Destination
[dequeue] =>
[value] => xxxxxxxxxxxx
)
)
)
I need it to end up looking like this.
[376339] => Array
(
[0] => Array
(
[id] => 1f422730-f54b-4e4d-9289-10258ce74446
[percentage] => 32
[destinations] => Array
(
[0] => stdClass Object
(
[id] => 59826
[destination_id] => 59826
[type] => Destination
[dequeue] =>
[value] => xxxxxxxxxxx
)
)
)
[1] => Array
(
[id] => 60dc4646-06ce-44d0-abe9-ee371847f4df
[percentage] => 68
[destinations] => Array
(
[0] => stdClass Object
(
[id] => 60046
[destination_id] => 60046
[type] => Destination
[dequeue] =>
[value] => xxxxxxxxxxxx
)
)
)
)
I'm not sure if this makes any sense, that's why I had my two inital outputs I need to have merged into one somehow. This is all coming from one huge json object and I'm just using json_decode($jsonStuff) to decode it.
Would this be easier if I added true in the decode function? If I could just search for it like I could in python, that would be neat. But as it is, I'm at a loss as to how to get the output I need.
Note: Input json CANNOT be changed, I have no affiliation with the people that created it.
First loop over your input array and create an array with the key as the id
$input = json_decode($json_input);
$output = array();
foreach($input as $obj){
$output[$obj->id] = $obj;
}
then you can build your other array by searching the id on the array key
$massive_search_array = array(376339 => array
(
0 => 1f422730-f54b-4e4d-9289-10258ce74446,
1 => 60dc4646-06ce-44d0-abe9-ee371847f4df
)
);
$final_output = array();
foreach($massive_search_array as $index => $searches){
foreach($searches as $search){
if(isset($output[$search])){
$final_output[$index][] = $output[$search];
}
}
}

Create a grouped array from another list of array items

I have an array of apps with ids and categories like this:
[apps] => Array
(
[0] => stdClass Object
(
[id] => 0
[categoryid] => 0
)
[1] => stdClass Object
(
[id] => 31265
[categoryid] => 12
)
[2] => stdClass Object
(
[id] => 15965
[categoryid] => 2
)
[3] => stdClass Object
(
[id] => 16554
[categoryid] => 12
)
)
I am trying to get all apps for a category based on this request. So, the resultant output for:
For CategoryId 12:
----------------
[apps] => Array
(
[0] => 31265
[1] => 16554
)
For CategoryId 2:
----------------
[apps] => Array
(
[0] => 15965
)
For CategoryId 0:
----------------
[apps] => Array
(
[0] => 0
)
I believe i need to use nested foreach loops, but is there an efficient method?
Thanks
You could cycle through them, and place them into category-arrays:
foreach ( $apps as $app ) {
$catArray[ $app[CategoryID] ][] = $app;
}
This should result in an array whose key represents a category, and whose nested arrays represent those apps in that category.
I've worked up a demo of this online at: http://codepad.org/WZXIvQ58

Categories