Comparing arrays inside multidimensional array - php

Basically i want to compare arrays inside a multidimensional array,
So i want to compare everyone with etc category 1 against each other, category 2 against earch other etc etc.
So what i really want to do is:
Compare every category against each other with this formula
versus - won = x
And then find out who has the lowest number and then update that last survivor from each category in the database (The winners)
Any ideas on how i can solve this the best?
$arr;
$stmt = $dbCon->prepare(" SELECT versus, won, imgId, category FROM rating_versus ");
$stmt->execute();
$stmt->bind_result($versus, $won, $imgId, $category);
while ($stmt->fetch()) {
$arr[] = array('category' => $category, 'id' => $imgId, 'versus' => $versus, 'won' => $won);
// echo $imgId . "<br> Versus: " . $versus . "<br> Won: " . $won . "<br> <br>";
}
$stmt->close();
This will output something like this
array(9) {
[0]=> array(4) { ["category"]=> int(1) ["id"]=> int(1) ["versus"]=> int(42) ["won"]=> int(21) }
[1]=> array(4) { ["category"]=> int(1) ["id"]=> int(5) ["versus"]=> int(47) ["won"]=> int(24) }
[2]=> array(4) { ["category"]=> int(1) ["id"]=> int(13) ["versus"]=> int(47) ["won"]=> int(23) }
[3]=> array(4) { ["category"]=> int(2) ["id"]=> int(2) ["versus"]=> int(45) ["won"]=> int(19) }
[4]=> array(4) { ["category"]=> int(2) ["id"]=> int(4) ["versus"]=> int(49) ["won"]=> int(25) }
[5]=> array(4) { ["category"]=> int(2) ["id"]=> int(7) ["versus"]=> int(44) ["won"]=> int(25) }
[6]=> array(4) { ["category"]=> int(3) ["id"]=> int(3) ["versus"]=> int(47) ["won"]=> int(29) }
[7]=> array(4) { ["category"]=> int(3) ["id"]=> int(6) ["versus"]=> int(50) ["won"]=> int(18) }
[8]=> array(4) { ["category"]=> int(3) ["id"]=> int(9) ["versus"]=> int(45) ["won"]=> int(24) }
}

To find the winner, you don't need to eliminate one by one, who has the lowest score.
Winner is who has the highest score.
So your code should be like following
$arr; $stmt = $dbCon->prepare(" SELECT versus, won, imgId, category FROM rating_versus ");
$stmt->execute();
$stmt->bind_result($versus, $won, $imgId, $category);
$winners=array();
while ($stmt->fetch()) {
$arr[] = array('category' => $category, 'id' => $imgId, 'versus' => $versus, 'won' => $won);
if(isset($winners[$category])) {
$curmax = $winners[$category]['won'];
if($won>$curmax) {
$winners[$category] = array('id'=>$imgId, 'won' => $won);
}
} else {
$winners[$category] = array('id'=>$imgId, 'won' => $won);
}
// echo $imgId . "<br> Versus: " . $versus . "<br> Won: " . $won . "<br> <br>";
}
$stmt->close();
print_r($winners);
This should work for this case

Related

Split continuous array into subarrays

I am trying to convert an array formatted as the following:
object(Categories_store_tree)#519 (1) {
["list_of_sections":"Categories_store_tree":private]=> array(5) {
["id"]=> int(1)
["name"]=> string(11) "Main Store"
["parent_id"]=> NULL
["children"]=> array(2) {
[0]=> array(5) {
["id"]=> int(2)
["name"]=> string(4) "Food"
["parent_id"]=> int(1)
["children"]=> array(0) { }
}
[1]=> array(5) {
["id"]=> int(3)
["name"]=> string(14) "Electronics"
["parent_id"]=> int(1)
["children"]=> array(2) {
[0]=> array(5) {
["id"]=> int(4)
["name"]=> string(8) "Headphones"
["parent_id"]=> int(3)
["children"]=> array(0) { }
}
[1]=> array(5) {
["id"]=> int(5)
["name"]=> string(5) "Smartphones"
["parent_id"]=> int(3)
["children"]=> array(0) { }
}
}
}
}
}
}
To this structure of array:
object(Categories_store_tree)#964 (1) {
["list_of_sections":"Categories_store_tree":private]=> array(5) {
[0]=> array(4) {
["id"]=> int(1)
["name"]=> string(11) "Main Store"
["parent_id"]=> NULL
}
[1]=> array(4) {
["id"]=> int(2)
["name"]=> string(4) "Food"
["parent_id"]=> int(1)
}
[2]=> array(4) {
["id"]=> int(3)
["name"]=> string(14) "Electronics"
["parent_id"]=> int(1)
}
[3]=> array(4) {
["id"]=> int(4)
["name"]=> string(8) "Headphones"
["parent_id"]=> int(3)
}
[4]=> array(4) {
["id"]=> int(5)
["name"]=> string(5) "Smartphones"
["parent_id"]=> int(3)
}
}
}
Currently I am doing in manual but the idea is to make it automatic. I have tried with this code, but it returns an empty array, I have also tried with a function but I have been stuck for a couple of days and don't know what to do.
$clean_array = array();
$cont = 0;
foreach ( $new_tree as $key => $value ) {
if ( is_array( $value ) ) {
$cont++;
foreach ( $value as $key1 => $value1 ) {
if ( is_array( $value1 ) ) {
$cont++;
foreach ( $value1 as $key2 => $value2 ) {
$clean_array[$cont][$key2] = $value2;
}
} else {
$clean_array[$cont][$key1] = $value1;
}
}
} else {
$clean_array[$cont][$key] = $value;
}
}
Maybe you could try something like this.
Convert the object To an array:
function objectToArray($d) {
if (is_object($d))
$d = get_object_vars($d);
return is_array($d) ? array_map(__METHOD__, $d) : $d;
}
Then:
$arr = objectToArray($object);
print_r($arr);
Source

Get ID of front-page for each sub-site has mixed results

I'm trying to get a list of all the homepage id's for all the sites on a WordPress multisite install. I'm using this code below to do that..
$subsites = get_sites();
foreach ( $subsites as $site ) {
switch_to_blog( $site->blog_id );
$site_data = [
'id' => get_current_blog_id(),
'home_id' => get_option( 'page_on_front' )
];
restore_current_blog();
$sites[] = $site_data;
}
But I'm getting some weird results using get_option( 'page_on_front' ). Some id's are returning as strings, others as integers, and a couple of them as false. Each site has a static front page assigned and the "Page on Front" option under the individual site settings do have values filled out. Any ideas on why I'm getting mixed results when trying to get the homepage id? Or is there another way to find the id other than the get_option( 'page_on_front' ) option?
$sites dump
array(11) {
[0]=>
array(2) {
["id"]=>
int(1)
["home_id"]=>
string(4) "1862"
}
[1]=>
array(2) {
["id"]=>
int(2)
["home_id"]=>
string(4) "2542"
}
[2]=>
array(2) {
["id"]=>
int(3)
["home_id"]=>
string(3) "905"
}
[3]=>
array(2) {
["id"]=>
int(4)
["home_id"]=>
int(1384)
}
[4]=>
array(2) {
["id"]=>
int(5)
["home_id"]=>
string(2) "13"
}
[5]=>
array(2) {
["id"]=>
int(6)
["home_id"]=>
string(4) "2885"
}
[6]=>
array(2) {
["id"]=>
int(7)
["home_id"]=>
bool(false)
}
[7]=>
array(2) {
["id"]=>
int(8)
["home_id"]=>
bool(false)
}
[8]=>
array(2) {
["id"]=>
int(9)
["home_id"]=>
int(7)
}
[9]=>
array(2) {
["id"]=>
int(10)
["home_id"]=>
string(1) "2"
}
[10]=>
array(2) {
["id"]=>
int(11)
["home_id"]=>
string(1) "5"
}
}

Array merge and removal of duplicate values

I have this foreach loop that outputs the below array, and I'm having a senior moment, I need it to return one array with no duplicate values, and I just can't it right.
foreach ( $post_groups as $post_group => $id ) {
group = $wpdb->get_row( $wpdb->prepare("SELECT * FROM $table_name WHERE ID = %d", $id), ARRAY_A);
$groups[$group['group_name']] = $group['group_name'] = unserialize( $group['group_users'] );
}
output:
array(2) {
["Registered Users"]=>
array(1) {
[0]=>
string(1) "2"
}
["Admin Users"]=>
array(2) {
[0]=>
string(1) "1"
[1]=>
string(1) "2"
}
}
Cheers
I believe the following is what you're after. Simply merge the arrays together and then ensure the result is unique.
$userIds = [
'Registered Users' => array(1,2,3),
'Admin Users' => array(3,4,5),
];
$allUserIds = array_unique(call_user_func_array('array_merge', $userIds));
var_dump($userIds);
/*
array(2) {
["Registered Users"]=>
array(3) {
[0]=>
int(1)
[1]=>
int(2)
[2]=>
int(3)
}
["Admin Users"]=>
array(3) {
[0]=>
int(3)
[1]=>
int(4)
[2]=>
int(5)
}
}
*/
var_dump($allUserIds);
/*
array(5) {
[0]=>
int(1)
[1]=>
int(2)
[2]=>
int(3)
[4]=>
int(4)
[5]=>
int(5)
}
*/
Use to php functions : array_unique(array_merge())
test code:
$userIds = array('RegisteredUsers' => array('A','a','b','B'),'AdminUsers' => array('C','c','B','d','a'));
$allUserIds = array_unique(array_merge($userIds['RegisteredUsers'], $userIds['AdminUsers']));
echo "<br><br>";
var_dump($userIds);
var_dump($allUserIds);

Remove Int keys and values from Multidimensional array PHP

I have this array (i can't change it) :
array(3) {
[0]=>
array(8) {
["kampania"]=> string(6) "dasdas"
[0]=> string(6) "dasdas"
["300x250"]=> int(1)
[1]=> int(1)
["160x600"]=> int(2)
[2]=> int(2)
["728x90"]=> int(3)
[3]=> int(3)
}
[1]=>
array(8) {
["kampania"]=> string(12) "aaaaaaaaaaaa"
[0]=> string(12) "aaaaaaaaaaaa"
["300x250"]=> int(4)
[1]=> int(4)
["160x600"]=> int(5)
[2]=> int(5)
["728x90"]=> int(6)
[3]=> int(6)
}
[2]=>
array(8) {
["kampania"]=> string(20) "AAAAAAAAAAAAAAAAAAAA"
[0]=> string(20) "AAAAAAAAAAAAAAAAAAAA"
["300x250"]=> int(7)
[1]=> int(7)
["160x600"]=> int(8)
[2]=> int(8)
["728x90"]=> int(9)
[3]=> int(9)
}
}
As you can see, I got repeated values, because the array as the defined key and then an integer key.
How can I create a function which will remove the integer key and value from array and return a new array already "clean"
the result expect should be like this:
array(3) {
[0]=>
array(8) {
["kampania"]=> string(6) "dasdas"
["300x250"]=> int(1)
["160x600"]=> int(2)
["728x90"]=> int(3)
}
[1]=>
array(8) {
["kampania"]=> string(12) "aaaaaaaaaaaa"
["300x250"]=> int(4)
["160x600"]=> int(5)
["728x90"]=> int(6)
}
[2]=>
array(8) {
["kampania"]=> string(20) "AAAAAAAAAAAAAAAAAAAA"
["300x250"]=> int(7)
["160x600"]=> int(8)
["728x90"]=> int(9)
}
}
Thanks Guys! I'm really sorry for ask it , but I loose already so much time trying to fix it by myself
function unset_num_keys($array)
{
$array_out = array();
foreach($array AS $k => $v)
{
if(is_array($v)) //value is an array, so clean it
{
$array_out[$k] = unset_num_keys($v); //clean "child" arrays
}
elseif(!is_numeric($k))
{
$array_out[$k] = $v; // key is "safe"
}
}
return $array_out;
}
Then
$clean_array = unset_num_keys($old_array);
Loop threw the array and if the key(index) is numeric then remove that item from the array.
foreach($level1_array as &$arr){
foreach ($arr as $key => $value) {
if (is_int($key)) {
unset($arr[$key]);
}
}
}
Example
<?php
$level1_array = array(
array(
"smith",
"name" => "smith",
"20",
"age"=>20
),
array(
"smith",
"name" => "smith",
"20",
"age"=>20
),
array(
"smith",
"name" => "smith",
"20",
"age"=>20
),
);
foreach($level1_array as &$arr){
foreach ($arr as $key => $value) {
if (is_int($key)) {
unset($arr[$key]);
}
}
}
var_dump($level1_array);
?>
You can try this code:
//$data = $yourData;
$newData = array();
foreach($data as $v){
array_push($newData,array_flip($v));
}

browsing an array by reference is changing it (no actions done)

edit:do not read the related topic, the answer below is clear and gives the solution, while the other topic just states the issue.
I have something weird here
My code looks like this:
var_dump($resultFlatTree);
foreach($resultFlatTree as &$element)
{
/*if(isset($element["action"]) && $element["action"] == "new")
{
//let's save the original ID so we can find the children
$originalID = $element["id"];
//now we get the object
$newObject = $setUpForDimension->createAnObject($dimension,$element,$customer);
$element['id'] = $newObject->getId();
echo "new";
//and let's not forget to change the parent_id of its children
$arrayFunctions->arrayChangingValues($resultFlatTree,"parent_id",$element['id'],$originalID);
$em->persist($newObject);
} */
}
$em->flush();
var_dump($resultFlatTree);
the code inside the foreach is commented to be sure that it's not what I'm doing that's changing the array.
here the array before the foreach:
array(3) {
[0]=>
array(10) {
["id"]=>
int(2)
["name"]=>
string(7) "Revenue"
["code"]=>
string(6) "700000"
["sense"]=>
string(2) "CR"
["lft"]=>
int(1)
["lvl"]=>
int(2)
["rgt"]=>
int(1)
["root"]=>
int(1)
["$$hashKey"]=>
string(3) "00D"
["parent_id"]=>
int(1)
}
[1]=>
array(10) {
["id"]=>
int(3)
["name"]=>
string(7) "Charges"
["code"]=>
string(6) "600000"
["sense"]=>
string(2) "DR"
["lft"]=>
int(3)
["lvl"]=>
int(2)
["rgt"]=>
int(4)
["root"]=>
int(1)
["$$hashKey"]=>
string(3) "00P"
["parent_id"]=>
int(4)
}
[2]=>
array(10) {
["id"]=>
int(4)
["name"]=>
string(6) "Energy"
["code"]=>
string(6) "606000"
["sense"]=>
string(2) "DR"
["lft"]=>
int(2)
["lvl"]=>
int(1)
["rgt"]=>
int(5)
["root"]=>
int(1)
["$$hashKey"]=>
string(3) "00E"
["parent_id"]=>
int(1)
}
}
and then after:
array(3) {
[0]=>
array(10) {
["id"]=>
int(2)
["name"]=>
string(7) "Revenue"
["code"]=>
string(6) "700000"
["sense"]=>
string(2) "CR"
["lft"]=>
int(1)
["lvl"]=>
int(2)
["rgt"]=>
int(1)
["root"]=>
int(1)
["$$hashKey"]=>
string(3) "00D"
["parent_id"]=>
int(1)
}
[1]=>
array(10) {
["id"]=>
int(3)
["name"]=>
string(7) "Charges"
["code"]=>
string(6) "600000"
["sense"]=>
string(2) "DR"
["lft"]=>
int(3)
["lvl"]=>
int(2)
["rgt"]=>
int(4)
["root"]=>
int(1)
["$$hashKey"]=>
string(3) "00P"
["parent_id"]=>
int(4)
}
[2]=>
&array(10) {
["id"]=>
int(4)
["name"]=>
string(6) "Energy"
["code"]=>
string(6) "606000"
["sense"]=>
string(2) "DR"
["lft"]=>
int(2)
["lvl"]=>
int(1)
["rgt"]=>
int(5)
["root"]=>
int(1)
["$$hashKey"]=>
string(3) "00E"
["parent_id"]=>
int(1)
}
}
As you can see, the last element is now changed and is by reference.
This completely messes up the processes I do with the array afterward.
Is that normal behavior ?
How can I avoid it ?
When you pass by reference to a foreach statement, you really should read the docs :)
http://php.net/manual/en/control-structures.foreach.php
In order to be able to directly modify array elements within the loop precede $value with &. In that case the value will be assigned by reference.
<?php
$arr = array(1, 2, 3, 4);
foreach ($arr as &$value) {
$value = $value * 2;
}
// $arr is now array(2, 4, 6, 8)
unset($value); // break the reference with the last element
?>
Reference of a $value and the last array element remain even after the foreach loop. It is recommended to destroy it by unset().
Basically, it's saying that when you pass by ref, it will remain locked on the last item due to an internal pointer.
The second user-comment at 40 points:
"Reference of a $value and the last array element remain even after the foreach loop. It is recommended to destroy it by unset()."
I cannot stress this point of the documentation enough! Here is a simple example of exactly why this must be done:
<?php
$arr1 = array("a" => 1, "b" => 2, "c" => 3);
$arr2 = array("x" => 4, "y" => 5, "z" => 6);
foreach ($arr1 as $key => &$val) {}
foreach ($arr2 as $key => $val) {}
var_dump($arr1);
var_dump($arr2);
?>
The output is:
array(3) { ["a"]=> int(1) ["b"]=> int(2) ["c"]=> &int(6) }
array(3) { ["x"]=> int(4) ["y"]=> int(5) ["z"]=> int(6) }
Notice how the last index in $arr1 is now the value from the last index in $arr2!
There are more comments which you will find interesting if you look for "reference" in that link.
tl;dr:
It's a bit funny/buggy/weird/un-patched.
Understand what the implications are as you write your code and make space for them.

Categories