Combining two arrays with unique field - php

Combining A array and B array and want the result show below
EDITED
a = {
[0]=> array(2) {
["pid"]=> string(1) "1"
["val1"]=> string(1) "1"
}
[1]=> array(2) {
["pid"]=> string(2) "12"
["val1"]=> string(1) "1"
}
[2]=> array(2) {
["pid"]=> string(2) "13"
["val1"]=> string(2) "79"
}
}
b = {
[0]=> array(2) {
["pid"]=> string(1) "1"
["val2"]=> string(1) "1"
}
[1]=> array(2) {
["pid"]=> string(2) "12"
["val2"]=> string(1) "1"
}
[2]=> array(2) {
["pid"]=> string(2) "13"
["val2"]=> string(2) "79"
}
[3]=> array(2) {
["pid"]=> string(2) "61"
["val2"]=> string(1) "1"
}
[4]=> array(2) {
["pid"]=> string(2) "62"
["val2"]=> string(2) "24"
}
}
Need help.

If this is coming from a data source, see if there's a way you can do this outside of PHP (e.g. MySQL's JOIN).
If PHP is your only answer, then below is a solution. Note that I changed the values of val1 and val2 so it was a bit more distinguishable.
You must have some sort of grouping constraint, which is configurable in the script below via $groupByKey. Judging by the common occurrence of PID, I assumed this as the subject key.
Also, if you have more than two arrays all following a similar schema (I have commented out $c as an example), you simply add more arguments to array_merge.
The idea is to keep merging each item in the cumulative list by using a fixed key as a "pointer," if you will.
<?php
$a = array(
array('pid' => 1, 'val1' => 'alpha'),
array('pid' => 3, 'val1' => 'bravo'),
array('pid' => 4, 'val1' => 'charlie')
);
$b = array(
array('pid' => 3, 'val2' => 'delta'),
array('pid' => 5, 'val2' => 'echo'),
array('pid' => 1, 'val2' => 'foxtrot'),
array('pid' => 8, 'val2' => 'golf')
);
/*
$c = array(
array('pid' => 3, 'val3' => 'hotel'),
array('pid' => 5, 'val1' => 'india'),
array('pid' => 1, 'val3' => 'juliette'),
array('pid' => 8, 'val3' => 'kilo')
);
*/
$groupByKey = 'pid'; // this becomes the fixed key
$merged = array_merge($a,$b); // array_merge($a,$b,$c); // cumulative container of all items in every subject array
$result = array(); // the result will be stored here, e.g. a temporary "table"
foreach ( $merged as $item ) { // $merged is essentially a table of subjects and $item is each row
if ( !isset($result[$item[$groupByKey]]) ) { // if we haven't come across this key yet
$result[$item[$groupByKey]] = array(); // initialize it
}
$result[$item[$groupByKey]] = array_merge($result[$item[$groupByKey]],$item); // consolidate all the cells for this row, later duplicate keys will cause values to be replaced
}
$result = array_values($result); // normalize the result keys, for the view they should increment rather than represent the group-by subjects
var_dump($result); // let's see how we did
?>
Provides:
array (size=5)
0 =>
array (size=3)
'pid' => int 1
'val1' => string 'alpha' (length=5)
'val2' => string 'foxtrot' (length=7)
1 =>
array (size=3)
'pid' => int 3
'val1' => string 'bravo' (length=5)
'val2' => string 'delta' (length=5)
2 =>
array (size=2)
'pid' => int 4
'val1' => string 'charlie' (length=7)
3 =>
array (size=2)
'pid' => int 5
'val2' => string 'echo' (length=4)
4 =>
array (size=2)
'pid' => int 8
'val2' => string 'golf' (length=4)

Related

need to change number of rows of an array

I have this array in indice.php, included into my page.php, is an array exported from the table "indice" of my db.
<?php
$indice = array(
array('id' => '1','def' => 'Admin'),
array('id' => '2','def' => 'Utente'),
array('id' => '31','def' => 'Aldwich Vertigos'),
array('id' => '32','def' => 'Celtic Newcastle'),
array('id' => '91','def' => 'Serie A'),
array('id' => '92','def' => 'Serie B'),
array('id' => '93','def' => 'Premier League'),
array('id' => '110','def' => 'Argentina'),
array('id' => '431','def' => 'Brisbane Road'),
array('id' => '432','def' => 'Kingstone Park'),
array('id' => '120','def' => 'Belgio') ); ?>
And my array is in this way:
array(416) {
[0]=>
array(2) {
["id"]=>
string(1) "1"
["def"]=>
string(5) "Admin"
}
[1]=>
array(2) {
["id"]=>
string(1) "2"
["def"]=>
string(6) "Utente"
}
[2]=>
array(2) {
["id"]=>
string(2) "31"
["def"]=>
string(16) "Aldwich Vertigos"
...etc...
then i print this:
<?php
include("functions.php");
include("auth.php");
include("db.php");
include("indice.php");
$indiceok = $indice['2']['def'];
echo $indiceok;
?>
'''
Well... My $indiceok stamps 'Aldwych Vertigos', but how could i obtain that $indiceok using the ID (2) stamps "Utente"?
I appreciate too a string which change my array in an array like this, using ID to identify my array selections:
array(416) {
[1]=>
array(2) {
["id"]=>
string(1) "1"
["def"]=>
string(5) "Admin"
}
[2]=>
array(2) {
["id"]=>
string(1) "2"
["def"]=>
string(6) "Utente"
}
**[31]**=>
array(2) {
["id"]=>
string(2) "31"
["def"]=>
string(16) "Aldwich Vertigos"
Many thanks and sorry for my question, i'm sure it's probably very easy to resolve, but i don't know how i can
You are looking for array_column.
By default it isolates a column in a multidimensional array but if you use the third argument you can make an array associative.
$yourarray = array_column($yourarray, Null, "id");
This will only work if id is unique.
If it's not unique, meaning you have two 31, the last subarray will be kept and the first will be truncated.
See result of your array here: https://3v4l.org/CJcJL
Alternatively, of your array is static you can just assign the keys manually in the code:
$indice = array(
"1" => array('id' => '1','def' => 'Admin'),
"2" => array('id' => '2','def' => 'Utente'),
"31" => array('id' => '31','def' => 'Aldwich Vertigos'),
"32" => array('id' => '32','def' => 'Celtic Newcastle'),
"91" => array('id' => '91','def' => 'Serie A'),
"92" => array('id' => '92','def' => 'Serie B'),
"93" => array('id' => '93','def' => 'Premier League'),
"110" => array('id' => '110','def' => 'Argentina'),
"431" => array('id' => '431','def' => 'Brisbane Road'),
"432" => array('id' => '432','def' => 'Kingstone Park'),
"120" => array('id' => '120','def' => 'Belgio') );

Sorting a Multi-Dimensional Array by sum of object values in PHP

I have the below multi dimensional array of products. Each array is a pair of products that make a product set, I need to order the multi dimensional array by the total price of each product set.
array(4) {
[0]=>
array(2) {
["product1"]=>
object(stdClass)#5075 (2) {
["product_id"]=>
string(4) "9416"
["price"]=>
string(6) "110.00"
}
["product2"]=>
object(stdClass)#5077 (2) {
["product_id"]=>
string(4) "9431"
["price"]=>
string(6) "100.00"
}
}
[1]=>
array(2) {
["product1"]=>
object(stdClass)#5065 (2) {
["product_id"]=>
string(4) "1254"
["price"]=>
string(6) "75.00"
}
["product2"]=>
object(stdClass)#5067 (2) {
["product_id"]=>
string(4) "9431"
["price"]=>
string(6) "62.00"
}
}
[2]=>
array(2) {
["product1"]=>
object(stdClass)#5055 (2) {
["product_id"]=>
string(4) "9416"
["price"]=>
string(6) "45.00"
}
["product2"]=>
object(stdClass)#5057 (2) {
["product_id"]=>
string(4) "9431"
["price"]=>
string(6) "50.00"
}
}
[3]=>
array(2) {
["product1"]=>
object(stdClass)#5045 (2) {
["product_id"]=>
string(4) "9416"
["price"]=>
string(6) "60.00"
}
["product2"]=>
object(stdClass)#5047 (2) {
["product_id"]=>
string(4) "9431"
["price"]=>
string(6) "25.00"
}
}
}
I need to sort the multi-dimensional array by the total sum of product1 + product2 in each array in ascending order. For example [1] should be above [0] as 75+62 is less than 110 +100.
If anyone can help me with this it would be greatly appreciated.
You can use usort() for this purpose:-
function comparePrice($a,$b)
{
$a_price = $a['product1']->price + $a['product2']->price;
$b_price = $b['product1']->price + $b['product2']->price;
if ($a_price ==$b_price) return 0;
return ($a_price<$b_price)? -1:1;
}
usort($array,'comparePrice');
A hardcoded working example:- https://3v4l.org/mTfu6
You need to use user-defined sorting
http://php.net/manual/en/function.usort.php
usort($products, function($a, $b) {
$prodA = $a['product1']['price'] + $a['product2']['price'];
$prodB = $b['product1']['price'] + $b['product2']['price'];
if($prodA == $prodB) return 0;
return ($prodA < $prodB) ? -1 : 1;
});
The php7+ "spaceship operator" (aka three-way-comparison operator) makes the syntax with usort() as clean and brief as possible.
Code: (Demo)
$array = [
[
"product1" => (object) ["product_id" => "9416", "price"=>"110.00"],
"product2" => (object) ["product_id"=>"9431", "price"=>"100.00"]
],
[
"product1" => (object) ["product_id" => "1254", "price"=>"75.00"],
"product2" => (object) ["product_id"=>"9431", "price"=>"62.00"]
],
[
"product1" => (object) ["product_id" => "9416", "price"=>"45.00"],
"product2" => (object) ["product_id"=>"9431", "price"=>"50.00"]
],
[
"product1" => (object) ["product_id" => "9416", "price"=>"60.00"],
"product2" => (object) ["product_id"=>"9431", "price"=>"25.00"]
]
];
usort($array, function($a, $b) {
return $a['product1']->price + $a['product2']->price <=> $b['product1']->price + $b['product2']->price;
});
var_export($array);
Output:
array (
0 => // sum = 85.00
array (
'product1' =>
(object) array(
'product_id' => '9416',
'price' => '60.00',
),
'product2' =>
(object) array(
'product_id' => '9431',
'price' => '25.00',
),
),
1 => // sum = 95.00
array (
'product1' =>
(object) array(
'product_id' => '9416',
'price' => '45.00',
),
'product2' =>
(object) array(
'product_id' => '9431',
'price' => '50.00',
),
),
2 => // sum = 137.00
array (
'product1' =>
(object) array(
'product_id' => '1254',
'price' => '75.00',
),
'product2' =>
(object) array(
'product_id' => '9431',
'price' => '62.00',
),
),
3 => // sum = 210.00
array (
'product1' =>
(object) array(
'product_id' => '9416',
'price' => '110.00',
),
'product2' =>
(object) array(
'product_id' => '9431',
'price' => '100.00',
),
),
)

How to compare two multidimensional arrays by certain keys in each?

I have two multidimensional arrays of the same structure.
Like this:
array(2) {
[0] =>
array(9) {
'id' =>
string(5) "44994"
'ersatzteil_id' =>
string(3) "120"
'lang' =>
string(6) "name2_tag2"
'title' =>
string(12) "Seitentüren"
'alias' =>
string(12) "seitentueren"
'content' =>
string(1610) "LOREM ISPUM BLALABLBL"
'on_main' =>
string(1) "0"
'disabled' =>
string(1) "1"
'short_text' =>
NULL
}
[1] =>
array(9) {
'id' =>
string(5) "44996"
'ersatzteil_id' =>
string(3) "122"
'lang' =>
string(6) "name1_tag1"
'title' =>
string(7) "Spoiler"
'alias' =>
string(7) "spoiler"
'content' =>
string(1513) "SOME OTHER RANDOM TEXT"
'on_main' =>
string(1) "0"
'disabled' =>
string(1) "0"
'short_text' =>
NULL
}
}
What I need to do is I need to compare first array with the second one.
I have to compare them by keys ersatzteil_id and content , and I find that they have same content I need to store element from first array in another new array, that wasn't existing before.
For example I need something like this, but more efficient:
if(array1[20]['ersatzteil_id'] == array2[145]['ersatzteil_id']
&& array1[20]['content'] == array2[145]['content']){
array3 = array1[20];
}
Try this code:-
$result = [];
foreach($array1 as $arr1){
foreach($array2 as $arr2){
if(($arr1['id'] == $arr2['id']) && ($arr1['ersatzteil_id'] == $arr2['ersatzteil_id'])){
$result[] = $arr1;
}
}
}
echo '<pre>'; print_r($result);

How can I print the lowest key of an array?

This is my array:
array(4) {
["1"]=>
array(3) {
[0]=>
string(2) "01"
[1]=>
string(2) "02"
[2]=>
string(2) "03"
}
["2"]=>
array(2) {
[0]=>
string(2) "01"
[1]=>
string(2) "02"
}
["3"]=>
array(1) {
[0]=>
string(2) "01"
}
["4"]=>
array(1) {
[0]=>
string(2) "01"
}
}
I want to print the lowest key, but only from the keys, that have less than 3 values.
echo min(array_keys($myarray));
gives me the result: 1
But key 1 already has 3 values, so the result I would need is 2. In the case every key has 3 values then print the next key (in this case would be 5)
I do not know how to do this. I am happy for every hint or advise.
This function iterate over your array and looks for all keys that has a value less then 3 values. It will return the first it founds if none is found the next key is return.
function getLowestKeyWithLessThan($yourArray, $number=3)
{
foreach ($yourArray as $key => $value) {
if (count($value) < $number)
return $key;
}
return count($yourArray) + 1;
}
If I run the following lines:
print "Answer " . getLowestKeyWithLessThan($yourArray);
print "\nAnswer " . getLowestKeyWithLessThan($AllKeysHasThreeElements);
This gives the answer:
Answer 2
Answer 5
Here is the data I used to test this:
$yourArray = array(
"1"=> array(
'0' => "01",
'1' => "02",
'2' => "03",
),
"2"=> array(
'0' => "01",
'1' => "02",
),
"3"=> array(
'0' => "01",
),
"4"=> array(
'0' => "01",
),
);
$threeValues = array(
'0' => "01",
'1' => "02",
'2' => "03",
);
$AllKeysHasThreeElements = array(
"1"=> $threeValues,
"2"=> $threeValues,
"3"=> $threeValues,
"4"=> $threeValues,
);
Of course the data could also been written like this:
$threeValues = array("01", "02", "03");
$yourArray = array($threeValues, array("01", "02"), array("01"), array("01"));
$AllKeysHasThreeElements = array($threeValues,$threeValues,$threeValues,$threeValues);

Clean up php array via alphabetical keys

I am extracting data from an xls document which returns as an array. The array keys however is not numeric, but resembles the cell column alphabetical digit. So effectively I have an array like this:
// Example array:
$array = array(
[0] => array(
"A" => "Name",
"B" => "Surname",
"C" => "",
"D" => "Telephone"
),
[1] => array(
"A" => "Name",
"B" => "Surname",
"C" => "",
"D" => "Telephone"
),
[2] => array(
"A" => "",
"B" => "",
"C" => "",
"D" => ""
)
);
Now the problem with the returned array is it does not filter the array at all, and I may have rows and rows of empty values in the rows.
I need a way to either clean up the array completely so remove empty rows and digits, but this may give me some issues with array consistancy later.
What I am looking for is a function which can chop rows in an array by a alphebitical digit. So effectively something like array_chop($array","C"); which would then effectively unset all the remainder rows key and value pairs from D onwards.
Is this possible? Is there a php function already I can use? I am sorry that I cannot provide sample code but I have no idea where to start. The array is substancially large, so I am looking for a memory efficient solution.
Thank you in advance!
If you want to copy only a small first portion of the column, this must be efficient:
<?php
$array = array(
0 => array(
"A" => "Name",
"B" => "Surname",
"C" => "",
"D" => "Telephone"
),
1 => array(
"A" => "Name",
"B" => "Surname",
"C" => "",
"D" => "Telephone"
),
2 => array(
"A" => "",
"B" => "",
"C" => "",
"D" => ""
)
);
$last_column = 1;
$n = count($array);
for ($i = 0; $i < $n; ++$i)
{
$copy = array();
$j = 0;
foreach($array[$i] as $key => $value)
{
if ($j <= $last_column)
{
$copy[$key] = $value;
++$j;
}
else
{
$array[$i] = $copy;
break;
}
}
}
var_dump($array);
This leaves only name and surname in the matrix:
array(3) {
[0]=>
array(2) {
["A"]=>
string(4) "Name"
["B"]=>
string(7) "Surname"
}
[1]=>
array(2) {
["A"]=>
string(4) "Name"
["B"]=>
string(7) "Surname"
}
[2]=>
array(2) {
["A"]=>
string(0) ""
["B"]=>
string(0) ""
}
}

Categories