Wrecking my brains for a while now and need your help
I have an array as below:
$originalArray = array(
array('id' => 1, 'sub-id' => 0),
array('id' => 2, 'sub-id' => 0),
array('id' => 3, 'sub-id' => 1),
array('id' => 4, 'sub-id' => 3),
array('id' => 5, 'sub-id' => 4),
array('id' => 6, 'sub-id' => 0),
array('id' => 7, 'sub-id' => 0),
array('id' => 8, 'sub-id' => 6),
array('id' => 9, 'sub-id' => 8),
array('id' => 10, 'sub-id' => 8)
);
and the logic here is
if sub-id of any element is equal to the id of another element,
then the array goes into the sub key of the parent element. i.e. sub-id 1 should go in 'sub' element of id 1 and sub-id 3 should go in 'sub' element of id 3
The required output of the above array is:
$requiredArray = array(
array('id' => 1,'sub-id' => 0,
'sub' => array(
array('id' => 3,'sub-id' => 1,
'sub' => array(
array('id' => 4,'sub-id' => 3,
'sub' => array(
array('id' => 5,'sub-id' => 4)
)
)
)
)
)
),
array('id' => 2,'sub-id' => 0),
array('id' => 6,'sub-id' => 0,
'sub' => array(
array('id' => 8,'sub-id' => 6,
'sub' => array(
array('id' => 9,'sub-id' => 8),
array('id' => 10,'sub-id' => 8)
)
)
)
),
array('id' => 7,'sub-id' => 0)
);
What have I tried so far
// $original array is the array shown above
function compare_subid($a, $b)
{
if ($a['sub-id'] == $b['sub-id']) return 0;
return ($a['sub-id'] < $b['sub-id']) ? -1 : 1;
}
usort($originalArray, 'compare_subid');
$newArray = array();
$newArray = create_multidimensional($originalArray, $newArray);
function create_multidimensional($originalArray, $newArray = null)
{
if ($newArray == null) $newArray = array();
array_walk($originalArray, function ($value, $key) use (&$newArray) {
//e($value);
if ($value['sub-id'] == 0) {
$newArray[] = $value;
} else {
foreach ($newArray as &$v) {
if ($v['id'] == $value['sub-id']) {
$v['sub'] = $value;
} else {
// not sure what to put here
}
}
}
});
return $newArray;
}
With this i am able to achieve a part of the $requiredArray which is as follows:
Array
(
[0] => Array
(
[id] => 6
[sub-id] => 0
[sub] => Array
(
[id] => 8
[sub-id] => 6
)
)
[1] => Array
(
[id] => 7
[sub-id] => 0
)
[2] => Array
(
[id] => 2
[sub-id] => 0
)
[3] => Array
(
[id] => 1
[sub-id] => 0
[sub] => Array
(
[id] => 3
[sub-id] => 1
)
)
)
Not sure if this is the correct method to use or there is any better way to do so.
If what I am doing is correct, I am not able to figure out what to input in the else statement of create_multidimensional function that I have created.
There is an easy way using references and only remove the ones with a sub-id at the very end:
// We need keys to be able to quickly map our assignments
foreach ($originalArray as $val) {
$array[$val["id"]] = $val;
}
// we first assign the arrays in a non-destructive way, so that we can easily find the
// appropriate key in the array
foreach ($array as $key => $val) {
if ($val["sub-id"] !== 0) {
$array[$val["sub-id"]]["sub"][] = &$array[$key];
}
}
// remove the ones from the first dimension which are somewhere deeper
foreach ($array as $key => $val) {
if ($val["sub-id"] !== 0) {
unset($array[$key]);
}
}
This is why objects in PHP are cool.
// Format all data into objects keyed by id
$input = array();
foreach ($originalArray as $el) {
$input[ $el['id'] ] = (object)($el + array('sub' => array()));
}
$result = array();
foreach ($input as $el) {
$sid = $el->{'sub-id'};
// Parent object: into result root
if ( !$sid ) {
$result[] = $el;
}
// Child object: into other object
else {
$input[$sid]->sub[] = $el;
}
}
print_r($result);
The obvious downside is that objects use ->prop syntax, which doesn't work well with -, so you have to ugly it: $el->{'sub-id'}.
And of course the result is a bunch of objects. May not be what you want.
Result (http://3v4l.org/8VMJr):
Array
(
[0] => stdClass Object
(
[id] => 1
[sub-id] => 0
[sub] => Array
(
[0] => stdClass Object
(
[id] => 3
[sub-id] => 1
[sub] => Array
(
[0] => stdClass Object
(
[id] => 4
[sub-id] => 3
[sub] => Array
(
[0] => stdClass Object
(
[id] => 5
[sub-id] => 4
[sub] => Array
(
)
)
)
)
)
)
)
)
[1] => stdClass Object
(
[id] => 2
[sub-id] => 0
[sub] => Array
(
)
)
[2] => stdClass Object
(
[id] => 6
[sub-id] => 0
[sub] => Array
(
[0] => stdClass Object
(
[id] => 8
[sub-id] => 6
[sub] => Array
(
[0] => stdClass Object
(
[id] => 9
[sub-id] => 8
[sub] => Array
(
)
)
[1] => stdClass Object
(
[id] => 10
[sub-id] => 8
[sub] => Array
(
)
)
)
)
)
)
[3] => stdClass Object
(
[id] => 7
[sub-id] => 0
[sub] => Array
(
)
)
)
Related
I have the following array
Array
(
[0] => Array
(
[shop] => 3
[price] => 332.00
)
[1] => Array
(
[shop] => 1
[price] => 3335.00
)
[2] => Array
(
[shop] => 3
[price] => 235.00
)
[3] => Array
(
[shop] => 1
[price] => 402.50
)
[4] => Array
(
[shop] => 3
[price] => 332.00
)
)
I need to group using shop and get get the minimum price of each shop in the array.
The expected result is as follows
Array
(
[0] => Array
(
[shop] => 3
[price] => 235.00
)
[1] => Array
(
[shop] => 1
[price] => 402.50
)
)
How will I do it?
You need to use additional variable
<?php
$arr = Array
(
0 => Array
(
'shop' => 3,
'price' => 332.00
),
1 => Array
(
'shop' => 3,
'price' => 232.00
),
2 => Array
(
'shop' => 1,
'price' => 232.00
),
3 => Array
(
'shop' => 3,
'price' => 432.00
),
4 => Array
(
'shop' => 1,
'price' => 132.00
),
);
$filtered = array();
foreach($arr as $prices){
if(FALSE === isset($filtered[$prices['shop']]) || $filtered[$prices['shop']]['price'] > $prices['price']){
$filtered[$prices['shop']] = $prices;
}
}
$filtered = array_values($filtered);
print_r($filtered);
This is very fast example how you can achieve this
It's rather simple.
Create a new array where you will host your stores as keys, and prices as values. What you want to do is to go through each element and first if the key does not exists in your new array, add it and its value. If however the key already exists, check if the current value is lower, and save it if true.
$grouped = [];
foreach ($arr as $k => $v) {
foreach ($k as $key => $value) {
if (isset($grouped[$key])) {
if ($value < $grouped[$key]) {
$grouped[$key] = $value;
}
} else {
$grouped[$key] = $value;
}
}
}
Your new array will look like this (store => price):
[
1 => 402.50,
3 => 235.00
]
This is the result of array after i build it using array_push function from mssql result.
Array
(
[0] => Array
(
[STICKER] => FALCON
[MONTH] => 1
[JUM] => 65826210.00
)
[1] => Array
(
[STICKER] => FALCON
[MONTH] => 2
[JUM] => 68070573.00
)
[2] => Array
(
[STICKER] => FALCON
[MONTH] => 3
[JUM] => 99053067.60
)
[3] =>
[4] => Array
(
[STICKER] => HRD
[MONTH] => 2
[JUM] => 1521400.00
)
[5] => Array
(
[STICKER] => HRD
[MONTH] => 3
[JUM] => 2093200.00
)
)
I need to convert array above into this structure:
Array
(
[0] => Array
(
[0] =>
[1] => 1
[2] => 2
[3] => 3
)
[1] => Array
(
[0] => FALCON
[1] => 65826210.00
[2] => 68070573.00
[3] => 99053067.60
)
[2] => Array
(
[0] => HRD
[1] => 0
[2] => 1521400.00
[3] => 2093200.00
)
)
Note:
Array[0] values would be 1,2,3 (this is actualy month, i just input up to 3 in order to get the code not too long. but it will be up to 12 (Jan - Dec)).
If from original array, there is none value (example from array[3]), then it will be convert to new array[2]->[1] with value 0.
Any help would be very appreciated.
Thanks all!.
Try this,
If any month is not mentioned from stickers the jum considered as 0,
$array = array(
array('STICKER' => 'FALCON', 'MONTH' => 1, 'JUM' => 65826210.00),
array('STICKER' => 'FALCON', 'MONTH' => 2, 'JUM' => 68070573.00),
array('STICKER' => 'FALCON', 'MONTH' => 3, 'JUM' => 99053067.60),
array(),
array('STICKER' => 'HRD', 'MONTH' => 2, 'JUM' => 1521400.00),
array('STICKER' => 'HRD', 'MONTH' => 3, 'JUM' => 2093200.00),
);
$result[0][] = '';
foreach ($array as $key => $res) {
if (!empty($res)) {
$result[0][$res['MONTH']] = $res['MONTH'];
$result1[$res['STICKER']][$res['MONTH']] = $res['JUM'];
}
}
foreach ($result1 as $key => $res) {
$fin = array();
foreach ($res as $key1 => $re) {
foreach ($result[0] as $key2 => $month) {
if ($month != '') {
if (array_key_exists($month, $res)) {
if (!array_key_exists($month, $fin) && $month == $key1) {
$fin[$month] = $re;
}
} else {
$fin[$month] = 0;
}
}
}
}
$result[] = array_merge(array($key), $fin);
}
echo'<pre>';
print_r($result);
echo'<pre>';
Result:
Array
(
[0] => Array
(
[0] =>
[1] => 1
[2] => 2
[3] => 3
)
[1] => Array
(
[0] => FALCON
[1] => 65826210
[2] => 68070573
[3] => 99053067.6
)
[2] => Array
(
[0] => HRD
[1] => 0
[2] => 1521400
[3] => 2093200
)
)
I hope this is used to achieve your output(you mentioned in above question)!!
try something like this
not the issue with the empty array i could not understand how the program would know that it is STICKER HRD so it will be filled with zero.But you could later check if every month "isset" and if it is not act as it is zero
$arr1=array(
array('STICKER'=>'FALCON','MONTH'=>1,'JUM'=>65826210.00),
array('STICKER'=>'FALCON','MONTH'=>2,'JUM'=>68070573.00),
array('STICKER'=>'FALCON','MONTH'=>3,'JUM'=>99053067.60),
array(),
array('STICKER'=>'HRD','MONTH'=>2,'JUM'=>1521400.00),
array('STICKER'=>'HRD','MONTH'=>3,'JUM'=>2093200.00),
);
$arr2=array();
$arr3=array();
$arr2[0][0]="";
foreach($arr1 as $key => $val){
if(!empty($val)){
$arr2[0][$val['MONTH']]=$val['MONTH'];
//group each STICKER
$arr3[$val['STICKER']][]=$val['JUM'];
}
}
//transfer the grouped data to arr2
foreach($arr3 as $key => $val){
$tmp_arr=array($key);
$arr2[]=array_merge($tmp_arr,$val);
}
print_r($arr2);
I have an array that looks like this:
getting array need to convert array as same key value as 0
foreach($array as $key=>$id){
$consumer_data[]=$this->App_model->get_session($id);
}
print_r($consumer_data);
Array
(
[0] => Array
(
[0] => Array
(
[ConsumerID] => 1
[name] => asdfd
)
[1] => Array
(
[ConsumerID] => 5
[name] => test
)
[2] => Array
(
[ConsumerID] => 3
[name] => test1
)
)
[1] => Array
(
[0] => Array
(
[ConsumerID] => 4
[name] => test4
)
)
i want to implement array like this in same key value as 0
Array
(
[0] => Array
(
[0] => Array
(
[ConsumerID] => 1
[name] => asdfd
)
[1] => Array
(
[ConsumerID] => 5
[name] => test
)
[2] => Array
(
[ConsumerID] => 3
[name] => test1
)
[3] => Array
(
[ConsumerID] => 4
[name] => test4
)
)
I am using PHP. Can anyone point me to a good starting point as to how I should go about doing this?
You can use array_merge():
$new_array[0] = array_merge($array[0], $array[1]);
Where $array is the first array.
SEE DEMO
OR for a more dynamic approach:
$new_array = array(0 => array());
foreach($array as $a) {
$new_array[0] = array_merge($new_array[0], $a);
}
SEE DEMO 2
The simpliest solution is to do it with:
$input = array(
array(
array('ConsumerID' => 1, 'name' => 'asdfd'),
array('ConsumerID' => 5, 'name' => 'test'),
array('ConsumerID' => 4, 'name' => 'test1'),
),
array(
array('ConsumerID' => 4, 'name' => 'test4'),
),
);
$output = array(
array()
);
foreach ($input as $data) {
$output[0] = array_merge($output[0], $data);
}
Try this->
$newArray = array();
foreach($values as $key=>$val){
$newArray [0][$key]=$val;
}
print_r($newArray);
Check this:
<?php
$arr[0] = array(0 => array("ConsumerID" => 1, "name" => "Ni"), 1 => array("ConsumerID" => 2, "name" => "Ab"));
$arr[1] = array(1 => array("ConsumerID" =>5, "name" => "GE"), 1 => array("ConsumerID" => 6, "name" => "DB"));
$new = array();
foreach($arr as $key => $value) {
foreach($value as $innerkey => $innervalue) {
$new[0][] = $innervalue;
}
}
print_r($new);
?>
I have the following array from PHP:
Array
(
[0] => Array
(
[ContractExhibitsData] => Array
(
[id] => 2
[exhibit_id] => 2
[parent_id] =>
)
[children] => Array
(
[0] => Array
(
[ContractExhibitsData] => Array
(
[id] => 98
[exhibit_id] => 2
[parent_id] => 2
)
[children] => Array
(
[0] => Array
(
[ContractExhibitsData] => Array
(
[id] => 99
[exhibit_id] => 2
[parent_id] => 98
)
[children] => Array
(
)
)
[1] => Array
(
[ContractExhibitsData] => Array
(
[id] => 100
[exhibit_id] => 2
[parent_id] => 98
)
[children] => Array
(
)
)
)
)
)
)
);
It is essentially a tree array, consisting of nodes with child nodes with more data. I want to iterate over this array using a recursive function to generate an array like this:
$return = Array
(
[2] => '1.',
[98] => '1.1.',
[99] => '1.1.1.',
[100] => '1.1.2.'
);
And so forth. Basically, it will be a bunch of Key-Value pairs where the array key is the 'id' of the element in ContractExhibitsData and the value is the numerical index.
I have the following function that I have been tinkering with, but it isn't getting me quite where I need to be.
private function getIndexes($data, $prefix = null) {
$indexes = array();
$count = 0;
if ($prefix) {
$prefix = $prefix . '.';
}
if (!empty($data['children'])) {
foreach($data['children'] as $child) {
$count++;
$indexes[$child['ContractExhibitsData']['id']] = $prefix.$count;
if (is_array($child['children']) && !empty($child['children'])) {
$subIndex = $this->getIndexes($child, $prefix.$count);
return $subIndex;
}
}
}
return $indexes;
}
Got it! See the working version here.
<?php
function getIndexes($data, $prefix = '') {
$indexes = array();
$count = 1;
if (!empty($prefix)) {
$prefix = $prefix . '.';
}
foreach ($data as $dataItem) {
$item = $dataItem['ContractExhibitsData'];
$index = $prefix.$count;
$indexes[$item['id']] = $index;
if(!empty($dataItem['children'])) {
$indexes = array_merge_recursive($indexes,getIndexes($dataItem['children'],$index));
}
$count++;
}
return $indexes;
}
$yourArray = array
(
0 => array (
'ContractExhibitsData' => array
(
'id' => 2,
'exhibit_id' => 2,
'parent_id' => null
),
'children' => array
(
0 => array
(
'ContractExhibitsData' => array
(
'id' => 98,
'exhibit_id' => 2,
'parent_id' => 2
),
'children' => array
(
0 => array
(
'ContractExhibitsData' => array
(
'id' => 99,
'exhibit_id' => 2,
'parent_id' => 98
),
'children' => array()
),
1 => array
(
'ContractExhibitsData' => array
(
'id' => 100,
'exhibit_id' => 2,
'parent_id' => 98
),
'children' => array ()
)
)
)
)
)
);
$result = getIndexes($yourArray);
var_dump($result);
One of your problems was that you had a return in your loop, thus breaking your loop. Also, you added null as a string since that was the default setting of your $prefix. You alos never iterated over the initial array but always just the children.
I want to compare two arrays in php. My arrays looks like this
Array (
[0] => Array ( [Id] => 1 [row1] => 1458)
[1] => Array ( [Id] => 2 [row1] => 16)
[2] => Array ( [Id] => 3 [row1] => 115)
[3] => Array ( [Id] => 4 [row1] => 18)
[4] => Array ( [Id] => 5 [row1] => 13)
[5] => Array ( [Id] => 6 [row1] => 13)
[6] => Array ( [Id] => 7 [row1] => 131)
)
Array (
[0] => Array ( [Id] => 1 [row1] => 158)
[1] => Array ( [Id] => 2 [row1] => 165)
[2] => Array ( [Id] => 3 [row1] => 111)
[3] => Array ( [Id] => 4 [row1] => 186)
[4] => Array ( [Id] => 5 [row1] => 3)
)
Firstly, array1 size and array2 sizes were not equal always. Id value in array1 may or may not present in array2, If the value is not present, function have to print the total index in array3, like
[someindex] => Array ( [Id] => 6 [row1] => 13 )
if it is present, function should subtract the row1 of array1 to row1 of array2 and print in array3, like this
[someindex] => Array ( [Id] => 1 [row1] => 1300)
and my final output should be,
Array (
[0] => Array ( [Id] => 1 [row1] => 1300)
[1] => Array ( [Id] => 2 [row1] => -149)
[2] => Array ( [Id] => 3 [row1] => 4)
[3] => Array ( [Id] => 4 [row1] => -168)
[4] => Array ( [Id] => 5 [row1] => 10)
[5] => Array ( [Id] => 6 [row1] => 13)
[6] => Array ( [Id] => 7 [row1] => 131)
)
Can any one help me in solving this problem.
$arr1 = Array (
0 => Array ('Id' => 1, 'row1' => 1458)
,1 => Array ('Id' => 2, 'row1' => 16)
,2 => Array ('Id' => 3, 'row1' => 115)
,3 => Array ('Id' => 4, 'row1' => 18)
,4 => Array ('Id' => 5, 'row1' => 13)
,5 => Array ('Id' => 6, 'row1' => 13)
,6 => Array ('Id' => 7, 'row1' => 131)
);
$arr2 = Array (
0 => Array('Id' => 1, 'row1' => 158)
,1 => Array('Id' => 2, 'row1' => 165)
,2 => Array('Id' => 3, 'row1'=> 111)
,3 => Array('Id' => 4, 'row1' => 186)
,4 => Array('Id' => 5, 'row1' => 3)
);
$final = array();
foreach($arr1 as $k => $sec)
{
$sub = 0;
foreach($arr2 as $sec2)
{
if($sec2['Id']==$sec['Id'])
{
$sub = $sec2['row1'];
break;
}
}
$sec['row1'] -= $sub;
//Or to save to another element:
//$sec['row2'] = $sec['row1']-$sub;
$final[] = $sec;
}
echo '<pre>'.print_r($final,true).'</pre>';
Output:
Array (
[0] => Array ( [Id] => 1 [row1] => 1300)
[1] => Array ( [Id] => 2 [row1] => -149)
[2] => Array ( [Id] => 3 [row1] => 4)
[3] => Array ( [Id] => 4 [row1] => -168)
[4] => Array ( [Id] => 5 [row1] => 10)
[5] => Array ( [Id] => 6 [row1] => 13)
[6] => Array ( [Id] => 7 [row1] => 131)
)
First, you either have to make the second array searchable by using the Id value as the keys or write a search function. I'm choosing the former:
$searchable = array_reduce($array2, function(&$result, $item) {
return $result + array($item['Id'] => $item['row1']);
}, array());
The array_reduce() function starts with an empty array and builds it using the array addition operator; this creates an array that can be dereferenced using the id.
Then you perform a map operation on the first array:
$array3 = array_map(function($item) use ($searchable) {
$value = isset($searchable[$item['Id']]) ? $searchable[$item['Id']] : 0;
$item['row1'] -= $value;
// $item['row2'] = $item['row1'] - $value;
return $item;
}, $array1);
Doing a map operation preserves the original array and creates a new one with the values you choose inside a callback function.
Don't know if this exactly what you want, but you can check if a key exists with array_key_exists:
$array3 = array();
foreach ($array1 as $k => $v) {
if (array_key_exists($k, $array2)) {
$array3[] = $v - $array2[$k];
} else {
$array3[] = $v;
}
}
This creates an indexing array ($new) in case the main keys don't match of in the original arrays.
$arr = array (
0 => array ( 'Id' => '1','row1' => 1458),
1 => array ( 'Id' => '2','row1' => 16),
2 => array ( 'Id' => '3','row1' => 115),
3 => array ( 'Id' => '4','row1' => 18),
4 => array ( 'Id' => '5','row1' => 13),
5 => array ( 'Id' => '6','row1' => 13),
6 => array ( 'Id' => '7','row1' => 131));
$arr2 = array (
0 => array ( 'Id' => '1','row1' => 158),
1 => array ( 'Id' => '2','row1' => 165),
2 => array ( 'Id' => '3','row1' => 111),
3 => array ( 'Id' => '4','row1' => 186),
4 => array ( 'Id' => '5','row1' => 3));
$new = array();
foreach ($arr2 as $key => $value){
$new[$value['Id']] = $value['row1'];
}
foreach ($arr as $key => $value){
if (isset($new[$value['Id']])){
$arr[$key]['row1'] -= $new[$value['Id']];
}
}
print_r($arr);