So I have a huge array of parts.
With a lot of help, I managed to associate related parts with a singular reference key.
Thus I have the following data;
array(
array ( 'make' => 'co1', 'model' => 'mdl1', 'part' => 'prt1', 'price' => '50', 'uid' => '1', 'rid' =>'1' ),
array ( 'make' => 'co1', 'model' => 'mdl1', 'part' => 'prt2', 'price' => '150', 'uid' => '2', 'rid' =>'1' ),
array ( 'make' => 'co1', 'model' => 'mdl2', 'part' => 'prt3', 'price' => '50', 'uid' => '3', 'rid' =>'2' ),
array ( 'make' => 'co2', 'model' => 'mdl3', 'part' => 'prt4', 'price' => '250', 'uid' => '4', 'rid' =>'2' )
)
Now, if you pay attention to Price, UID and RID - you will see a pattern.
The first two array elements belong together, as do the last 2 elements (they have the same Related ID).
The problem is - the prices are divergent!
I need a way to do the following;
1) add a flag in the array for divergent pricing
2) change all prices to the lowest one
As a bonus - I'm also looking to create a "parent" element ... thus I'd add two new sub-arrays (one for RID1 and one for IRD2), combining the values of MDL, PART and MAKE etc.).
I've attempted this myself, and generally created a muddle.
I can foreach over and generate a new array with 1 child per RID - but I cannot append the values of multiple child arrays from the original :( (I thought I was getting close, but added the price values!).
$composite = array();
foreach($data as $value) {
if(array_key_exists($value['rid'], $composite)) {
$composite[$value['rid']] += $value['price'];
//$composite[$value['rid']] = array('prices'=>$value['price']);
} else {
$composite[$value['rid']] = $value['price'];
//$composite[$value['rid']] = array('prices'=>$value['price']);
}
}
foreach($composite as $key=>$out){
echo $key ." : "; print_r($out); echo "<br/>";
}
So ... for the sake of clarity ... I'd like to take this;
array(
array ( 'make' => 'co1', 'model' => 'mdl1', 'part' => 'prt1', 'price' => '50', 'uid' => '1', 'rid' =>'1' ),
array ( 'make' => 'co1', 'model' => 'mdl1', 'part' => 'prt2', 'price' => '150', 'uid' => '2', 'rid' =>'1' ),
array ( 'make' => 'co1', 'model' => 'mdl2', 'part' => 'prt3', 'price' => '70', 'uid' => '3', 'rid' =>'2' ),
array ( 'make' => 'co2', 'model' => 'mdl3', 'part' => 'prt4', 'price' => '70', 'uid' => '4', 'rid' =>'2' )
)
and end up with this;
array(
// New Parent (for rid=1's)
array ( 'make' => 'co1', 'model' => 'mdl1', 'part' => 'prt1,prt2', 'price' => '50', 'uid' => '1', 'rid' =>'1', 'divprice' => true ),
array ( 'make' => 'co1', 'model' => 'mdl1', 'part' => 'prt1', 'price' => '50', 'uid' => '2', 'rid' =>'1', 'divprice' => true ),
// Price changed from 150 to 50 - based on lowest price for matching rid
array ( 'make' => 'co1', 'model' => 'mdl1', 'part' => 'prt2', 'price' => '150', 'uid' => '3', 'rid' =>'1', 'divprice' => true ),
// New Parent (for rid=2's)
array ( 'make' => 'co1, co2', 'model' => 'mdl2, mdl3', 'part' => 'prt3,prt4', 'price' => '70', 'uid' => '4', 'rid' =>'2', 'divprice' => false),
array ( 'make' => 'co1', 'model' => 'mdl2', 'part' => 'prt3', 'price' => '70', 'uid' => '5', 'rid' =>'2', 'divprice' => false ),
array ( 'make' => 'co2', 'model' => 'mdl3', 'part' => 'prt4', 'price' => '70', 'uid' => '6', 'rid' =>'2', 'divprice' => false )
)
I know it looks complicated - but I've seen "similar" functionality in code - but for the life of me I cannot get any of it to work ... I end up merging and losing values, or adding them together (so the price ends up as 200 instead of 50 etc.)
Thank you.
Not sure what you mean by a flag for divergent prices, but for the bit where you want to update all the prices with the lowest one, you could do something like:
// Your data
$products = array(
array ( 'make' => 'co1', 'model' => 'mdl1', 'part' => 'prt1', 'price' => '50', 'uid' => '1', 'rid' =>'1' ),
array ( 'make' => 'co1', 'model' => 'mdl1', 'part' => 'prt2', 'price' => '150', 'uid' => '2', 'rid' =>'1' ),
array ( 'make' => 'co1', 'model' => 'mdl2', 'part' => 'prt3', 'price' => '70', 'uid' => '3', 'rid' =>'2' ),
array ( 'make' => 'co2', 'model' => 'mdl3', 'part' => 'prt4', 'price' => '70', 'uid' => '4', 'rid' =>'2' )
);
// Get lowest product
function get_lowest_product($products) {
$lowest = 0;
foreach ($products as $key => $product) {
$price = (int)$product["price"];
if ($price < $lowest || $lowest == 0) {
$lowest = (int)$product["price"];
}
}
return $lowest;
}
// Replace value in array
function replace_all_prices_to_lowest($products, $lowest) {
foreach ($products as $key => &$product) {
$product["price"] = (string)$lowest;
}
return $products;
}
// Testing
$lowest = get_lowest_product($products);
$replaced = replace_all_prices_to_lowest($products, $lowest);
var_dump($replaced);
Related
i have a problem with this array, i need get sum form string merge with same key
$data = array(
0 => array(
'name' => 'Alfa Edison, Dwiki',
'budget' => 3700,
),
1 => array(
'name' => 'Maverick Sam',
'budget' => 500,
),
2 => array(
'name' => 'Dwiki',
'budget' => 1000,
),
3 => array(
'name' => 'Steve, Dwiki',
'budget' => 2000,
),
4 => array(
'name' => 'Alfa Edison',
'budget' => 700,
),
5 => array(
'name' => 'Maverick Sam',
'budget' => 4000,
),
6 => array(
'name' => 'Steve, Alfa Edison',
'budget' => 334,
),
);
i want the result this:
array(
0 => array(
'name' => 'Alfa Edison',
'budget' => 4734,
),
1 => array(
'name' => 'Dwiki',
'budget' => 6700,
),
2 => array(
'name' => 'Maverick Sam',
'budget' => 4500,
),
3 => array(
'name' => 'Steve',
'budget' => 2334,
),
);
How to merge String with same Key and Sum the Budget. i try to for each but i'm fail.
i try array_reduce and explode the name but fail.
The problem is that each of the "keys" (names) is really more than one key. So as you iterate the input array you'll need to split those up, then add an inner loop to use the names as keys in the result.
foreach ($data as $item) {
// separate the names
$names = explode(', ', $item['name']);
// iterate the names and set/increase values for them in the result array
foreach ($names as $name) {
$result[$name]['name'] = $name;
$result[$name]['budget'] = $item['budget'] + ($result[$name]['budget'] ?? 0);
}
}
// remove the string keys if necessary
$result = array_values($result);
I have two arrays.
$primary = array(
[0] => array(
'name' => 'PPT Shop',
'place_id' => '1000',
'category' => '220,221',
'address' =>
),
[1] => array(
'name' => 'Meat Shop',
'place_id' => '1001',
'category' => '220,221'
'address' =>
),
[2] => array(
'name' => 'Bikini Shop',
'place_id' => '1010',
'category' => '100,102'
'address' =>
),
[3] => array(
'name' => 'Knife Shop',
'place_id' => '1012',
'category' => '1,3'
'address' =>
)
)
$moredata = array(
[0] => array(
'id' => '1000',
'category' => '900,901'
'address' => '35 Lawrence Park',
'phone' => '9000000099'
),
[1] => array(
'id' => '1001',
'category' => '909,300'
'address' => '39 Park Avenue',
),
[2] => array(
'id' => '1010',
'category' => '50,45'
'address' => '35 Trump Park',
'phone' => '8900000099'
)
)
I want to compare each data of $moredata with each data of $primary, and check if the place_id from $primary exists in $moredata. If it matches, then the corresponding records of that particular key will be updated. For example,
$newPrimary = array(
[0] => array(
'name' => 'PPT Shop',
'place_id' => '1000',
'category' => '220,221,900,901',
'address' => '35 Lawrence Park',
'phone' => '9000000099'
),
[1] => array(
'name' => 'Meat Shop',
'place_id' => '220,221,1001',
'category' => '220,221,909,300',
'address' => '39 Park Avenue',
),
[2] => array(
'name' => 'Bikini Shop',
'place_id' => '1010',
'category' => '100,102,50,45'
'address' => '35 Trump Park',
'phone' => '8900000099'
),
[3] => array(
'name' => 'Knife Shop',
'place_id' => '1012',
'category' => '1,3'
'address' =>
)
)
place_id(1000) of primary matches with id(1000) of moredata, so the place_id(1000) of newPrimary is like this:-
array(
'name' => 'PPT Shop',
'place_id' => '1000',
'category' => '220,221,900,901', // the categories get concated
'address' => '35 Lawrence Park',
'phone' => '9000000099'
)
However, for place_id(1001) of primary doesn't have phone field, so the id(1001) of newPrimary is like this:-
array(
'name' => 'Meat Shop',
'place_id' => '1001',
'category' => '220,221,909,300',
'address' => '39 Park Avenue',
)
place_id(1012) has no match, so it remains unchanged.
How can I create an array similar to newPrimary? It would be better if we can append the fields from moredata to the corresponding record from primary. I achieved the same using double foreach loop. I want to achieve this is a way to have lesser execution time.
foreach($primary as $key_fs => $prm)
{
foreach($moredata as $key_place => $pc)
{
if($prm['place_id'] == $pc['id'])
{
if(isset($pc['address']) && !empty($pc['address']))
$primary[$key_fs]['address'] = $pc['address'];
if(isset($pc['phone']) && !empty($pc['phone']))
$primary[$key_fs]['phone'] = $pc['phone'];
if(isset($pc['category']) && !empty($pc['category']))
$primary[$key_fs]['category'] .= ','.$pc['category'];
break;
}
}
}
Note:- The two arrays will have same dimension, but may not have same order.
You can use array_column to make the 2 arrays into multidimensional array. Use array_replace_recursive to merge the arrays.
You can use array_values if you want a simple array instead of multi dimensional output.
$primary = //Your array
$moredata = //Your array
$result = array_replace_recursive (array_column($primary, null, 'id') ,array_column($moredata, null, 'id') );
$result = array_values($result); //To convert the multidimensional array to simple array
Update:
You can use array_column to make a temp array for $moredata. This will make it easier to check if the id exist. Use the foreach to loop thru the array. If id exist on $moredata, simply concatenate the category.
$newMoreData = array_column($moredata, null, 'id');
$newPrimary = array();
foreach( $primary as $val ) {
if ( isset( $newMoreData[$val['place_id']] ) ) {
$temp = array_merge( $val, $newMoreData[$val['place_id']] );
$temp['category'] = $val['category'] . ',' . $newMoreData[$val['place_id']]['category'];
unset($temp['id']);
$newPrimary[] = $temp;
} else {
$newPrimary[] = $val;
}
}
From my SQL query, I will get the following array as a result. This is the last result I can get from SQL.I cant change any SQL because of some constraint.
I need to check if the same id exists or not and if it does need to count them and remove one of the duplicate array having the same id.
Sample array is
$array = array(
0 => array(
'id' => '17',
'status' => 1,
),
1 => array(
'id' => '18',
'status' => 1,
),
2 => array(
'id' => '21',
'status' => 1,
),
3 => array(
'id' => '5',
'status' => 2,
),
4 => array(
'id' => '18',
'status' => 1,
),
5 => array(
'id' => '22',
'status' => 5,
),
6 => array(
'id' => '6',
'status' => 1,
),
);
I need to check if they have a duplicate id or not, if yes need to count them and remove one of the duplicates.We need to preserve the array structure.
End Results should be
array(
0 => array(
'id' => '17',
'status' => 1,
'count'=1,
),
1 => array(
'id' => '18',
'status' => 1,
'count'=2,
),
2 => array(
'id' => '21',
'status' => 1,
'count'=1,
),
3 => array(
'id' => '5',
'status' => 2,
'count'=1,
),
4 => array(
'id' => '22',
'status' => 5,
'count'=1,
),
5 => array(
'id' => '6',
'status' => 1,
'count'==>1,
),
)
You can Check it by this way but duplicate entry still in the array.
$ids = array();
foreach ($array as $key => $value)
{
$ids[] = $value['id'];
$count = array_count_values($ids);
}
for($i = 0; $i < count($array);$i++)
{
$array[$i]['count'] = $count[$array[$i]['id']];
}
You can do this with the array_unique function.
Use it like so:
$a=array("a"=>"red","b"=>"green","c"=>"red");
print_r(array_unique($a));
Which outputs:
Array ( [a] => red [b] => green )
I have an complicated array that looks like this:
$input=array(
(int) 0 => array(
'XXX' => array(
'id' => '7',
'p_id' => '1',
'address' => '9463',
'arrival_time' => '2014-05-01 03:30:00'
),
'YYY' => array(
'id' => '1',
'iden' => '1111',
'name' => 'Tom'
)
),
(int) 1 => array(
'XXX' => array(
'id' => '9',
'p_id' => '2',
'address' => '9469',
'arrival_time' => '2014-05-27 16:43:58'
),
'YYY' => array(
'id' => '2',
'iden' => '2222',
'name' => 'Sam'
)
),
(int) 2 => array(
'XXX' => array(
'id' => '3',
'p_id' => '3',
'address' => '9462',
'arrival_time' => '2014-04-21 14:05:00'
),
'YYY' => array(
'id' => '3',
'iden' => '3333',
'name' => 'James'
)
)
)
I would like to convert it such that it looks like this;
$output=array(
(int) 0 => array(
'name' => 'Tom',
'iden' => '1111',
'address' => '9463'
),
(int) 1 => array(
'name' => 'Sam',
'iden' => '2222',
'address' => '9469'
),
(int) 2 => array(
'name' => 'James',
'iden' => '3333',
'address' => '9462'
)
I wrote some code to solve this problem:
foreach ( $input as $key => $value)
{
$output['name']=$input[$key]['YYY']['name'];
$output['iden']=$input[$key]['YYY']['iden'];
$output['address']=$input[$key]['XXX']['address'];
}
Unfortunately, it retrieves only the last element of the input array.
Can someone more experienced help?
Thank you very much.
You are overwriting the values in each iteration, as you always write to $output['name'] etc.
foreach ( $input as $key => $value)
{
$output[$key] = array(
'name' => $value['YYY']['name'],
'iden' => $value['YYY']['iden'],
'address' => $value['XXX']['address']
);
}
The key here is using $output[$key] instead of $output - this way you will add a new element in each iteration.
Also $input[$key] and $value are equivalent, so I used the shorter variant ;)
Try this in your foreach loop :-
foreach ( $input as $key=>$value)
{
$output[$key]['name']=$value['YYY']['name'];
$output[$key]['iden']=$value['YYY']['iden'];
$output[$key]['address']=$value['XXX']['address'];
}
You have to add an index to the array in the foreach: $output[$key]["name"] = ...;
How can I get the all the 'name' and 'city' value back in an array from the following multidimensional array?
$myarray=Array(Array('name' => 'A','id' => '1', 'phone' => '416-23-55',
Base => Array ('city' => 'toronto'),'EBase' => Array('city' => 'North York'),
'Qty' => '1'), (Array('name' =>'B','id' => '1','phone' => '416-53-66','Base' =>
Array ('city' => 'qing'), 'EBase' => Array('city' => 'chong'),'Qty' => '2')));
I expect the returned value be
$namearray=Array('A','B');
$basecityarray=Array('toronto','qing');
$Ebasecityarray=Array('North York','chong');
Thank you!
You can definitely try something like this:
$shop = array( array( 'Title' => "rose",
'Price' => 1.25,
'Number' => 15
),
array( 'Title' => "daisy",
'Price' => 0.75,
'Number' => 25,
),
array( 'Title' => "orchid",
'Price' => 1.15,
'Number' => 7
)
);
You can access the first row as
echo $shop[0][0]." costs ".$shop[0][1]." and you get ".$shop[0][2]."<br />";
or $shop[0]->Title will return to you rose.