PHP: Get result from arrays. - php

Sorry for the title. its little difficult for me to explain. I've spent almost few hours to figure this out, but failed. So I'm posting it here.
I have following array
Array
(
[0] => Array
(
[0] => a
[1] => b
[2] => c
)
[1] => Array
(
[0] => p
[1] => q
[2] => r
)
[2] => Array
(
[0] => w
[1] => x
[2] => y
[3] => z
)
)
The array could have any number of elements.
What i need to do is create another array based on above array.
Array
(
[0] => Array
(
[0] => a
[1] => p
[2] => w
)
[1] => Array
(
[0] => b
[1] => q
[2] => x
)
[2] => Array
(
[0] => c
[1] => r
[2] => y
)
[3] => Array
(
[0] => Z
)
)
Any hints will be appreciated.
Thanks

If PHP < 5.5 or you don't want to use array_column-solution
$newArray = array();
foreach($array as $row)
foreach($row as $key => $value){
if (!isset($newArray[$key]))
$newArray[$key] = array();
$newArray[$key][] = $value;
}

Upgrade to PHP 5.5 if you aren't already on it, then use array_column

Just try with array_walk_recursive:
$input = [
['a', 'b', 'c'],
['p', 'q', 'r'],
['w', 'x', 'y', 'z'],
];
$output = [];
array_walk_recursive($input, function($value, $index) use (&$output) {
if (!isset($output[$index])) {
$output[$index] = [];
}
$output[$index][] = $value;
});
Output:
array (size=4)
0 =>
array (size=3)
0 => string 'a' (length=1)
1 => string 'p' (length=1)
2 => string 'w' (length=1)
1 =>
array (size=3)
0 => string 'b' (length=1)
1 => string 'q' (length=1)
2 => string 'x' (length=1)
2 =>
array (size=3)
0 => string 'c' (length=1)
1 => string 'r' (length=1)
2 => string 'y' (length=1)
3 =>
array (size=1)
0 => string 'z' (length=1)

Related

How to parse this format?

I'm trying to parse a string which looks like this :
"['x','y','z',['a'],[],[['name','2'],['name','40']]]"
I would like to put everythings in an array like this :
0 => string 'x' (length=1)
1 => string 'y' (length=1)
2 => string 'z' (length=1)
3 =>
array (size=1)
0 => string 'a' (length=1)
4 =>
array (size=0)
empty
5 =>
array (size=2)
0 =>
array (size=2)
0 => string 'name' (length=4)
1 => string '2' (length=1)
1 =>
array (size=2)
0 => string 'name' (length=4)
1 => string '40' (length=2)
Is there a proper way to do it because I tried to make a bunch of functions, but at the end it's always a mess and it doesn't work.
Thats nearly a JSON String, so make it into one and from there its easy running
$nearlyJson = "['x','y','z',['a'],[],[['name','2'],['name','40']]]";
$nowItsJson = str_replace("'", '"', $nearlyJson );
$NowItsAPHPArray = json_decode($nowItsJson );
print_r($NowItsAPHPArray );
RESULT
Array
(
[0] => x
[1] => y
[2] => z
[3] => Array
(
[0] => a
)
[4] => Array
(
)
[5] => Array
(
[0] => Array
(
[0] => name
[1] => 2
)
[1] => Array
(
[0] => name
[1] => 40
)
)
)

php array count same key after merge to separate comma

I using codeigniter 3.x version.
This is value passed to the ajax.
Array (
[0] => 10:4
[1] => 11:1
[2] => 12:2
[3] => 13:3
[4] => 14:4
[5] => 15:5
[6] => 16:4
[7] => 17:3
[8] => 18:2
[9] => 19:1
[10] => 1:4 // duplicate
[11] => 1:5 // duplicate
[12] => 20:2
[13] => 21:3
[14] => 22:4
[15] => 23:5
[16] => 24:4 // duplicate
[17] => 24:5 // duplicate
[18] => 25:2
[19] => 2:5
[20] => 3:4
[21] => 4:4
[22] => 5:4
[23] => 6:3
[24] => 7:2
[25] => 8:3
[26] => 9:2 // duplicate
[27] => 9:4 // duplicate
)
I want to insert into the database, Processing the array
First, sort to use natsort($data)
1:4
1:5
2:5
3:4
4:4
5:4
6:3
7:2
8:3
9:2
10:4
11:1
12:2
13:3
14:4
15:5
16:4
17:3
18:2
19:1
20:2
21:3
22:4
23:5
24:4
24:5
25:2
25:5
It was satisfactory.
but
1:4
1:5
24:4
24:5
25:2
25:5
is has duplicate value
My questions is
1:4
1:5
24:4
24:5
25:2
25:5
to
1:4,5
2:5
3:4
.
.
24:4,5
25:2,5
How should this be handled on php?
This might help -
$new= [];
foreach($ar as $v) {
$temp = explode(':', $v);
$new[$temp[0]][] = $temp[1];
}
foreach($new as $k => $v) {
$new[$k] = $k . ':' . implode(',', $v);
}
DEMO
$keys = array();
$list = array(
'1:4','1:5','2:1','3:4','4:1','4:2'
);
// Seach the keys
foreach($list as $item){
$key = substr($item,0,strpos($item, ':'));
$val = substr($item,strpos($item, ':')+1);
if(!isset($keys[$key])) $keys[$key] = array();
$keys[$key][] = $val;
}
//And now you can handle how do you want
$final = array();
foreach($keys as $key => $value){
$final[$key] = implode(',',$value);
}
var_dump($list);
var_dump($keys);
var_dump($final);
===================== OUTPUT =====================
$list:
array (size=6)
0 => string '1:4' (length=3)
1 => string '1:5' (length=3)
2 => string '2:1' (length=3)
3 => string '3:4' (length=3)
4 => string '4:1' (length=3)
5 => string '4:2' (length=3)
$keys:
array (size=4)
1 =>
array (size=2)
0 => string '4' (length=1)
1 => string '5' (length=1)
2 =>
array (size=1)
0 => string '1' (length=1)
3 =>
array (size=1)
0 => string '4' (length=1)
4 =>
array (size=2)
0 => string '1' (length=1)
1 => string '2' (length=1)
$final:
array (size=4)
1 => string '4,5' (length=3)
2 => string '1' (length=1)
3 => string '4' (length=1)
4 => string '1,2' (length=3)
You can achieve it in two step ..
Get all first part and set values to all duplicates by making it key
Reverse engineering to achieve result
$a=array('1:4' ,'1:5' ,'24:4','24:5','25:2','25:5');//input here
$temp=array();
$result=array();
foreach($a as $v)
{
$part=explode(":",$v);
if(isset($temp[$part[0]]))
$temp[$part[0]].=",".$part[1];
else
$temp[$part[0]]=$part[1];
}
foreach($temp as $k=>$v)
{
$result[]=$k.":".$v;
}
print_r($result);
OUPTUT
Array ( [0] => 1:4,5 [1] => 24:4,5 [2] => 25:2,5 )

How to convert a recursive multidimensional array to a straight multidimensional array in PHP?

I have search for a solution for this but couldn't find anything giving me a "straight" multidimensional array back. Flatten is probably not the solution as long as i want to preserve the original sub structure?
In additional i want to summarize qty when the key is repeating.
This is my original array:
Array
(
[60002] => Array
(
[50001] => Array
(
[50002] => Array
(
[10001] => Array
(
[flag] => B
[qty] => 1
)
[10002] => Array
(
[flag] => B
[qty] => 1
)
[10003] => Array
(
[flag] => B
[qty] => 2
)
[flag] => M
[qty] => 1
)
[flag] => M
[qty] => 1
)
[flag] => G
[qty] => 1
)
[10001] => Array
(
[flag] => B
[qty] => 1
)
)
What i basically want is to create a new array looking like this:
Array
(
[10001] => Array
(
[flag] => B
[qty] => 2
)
[10002] => Array
(
[flag] => B
[qty] => 1
)
[10003] => Array
(
[flag] => B
[qty] => 2
)
[50001] => Array
(
[flag] => M
[qty] => 1
)
[50002] => Array
(
[flag] => M
[qty] => 1
)
[60002] => Array
(
[flag] => G
[qty] => 1
)
)
This is tested.
The key is intval().
$value['qty'] += intval($newArray[$key]['qty']);
If the [$key]['qty'] does not exist the intval() will return a zero. This is much faster than using an if else to check if a [$key]['qty'] already exists.
The only possible problem I could anticipate is if the Flag value is different when the key value is the same:
[10001] => Array(
[flag] => M
[qty] => 1
),
[10001] => Array(
[flag] => B
[qty] => 1
)
When this is an issue I resolve the priority with a logic table in an array.
$priority['M']['B'] = 'M'
$priority['B']['M'] = 'M'
$priority['']['M'] = 'M'
$priority['M'][''] = 'M'
$priority['B'][''] = 'B'
$priority['B'][''] = 'B'
settype($newArray[$key]['flag'],'string');
[$newArray[$key]['flag'] = $priority[$value['flag']][$newArray[$key]['flag']]
Data:
$array = array('60002' => Array('50001' => Array('50002' => Array('10001' => Array('flag' => 'B','qty' => 1),'10002' => Array('flag' => 'B','qty' => 1),'10003' => Array('flag' => 'B','qty' => 2),'flag' => 'M','qty' => 1),'flag' => 'M','qty' => 1),'flag' => 'G','qty' => 1),'10001' => Array('flag' => 'B','qty' => 1));
PHP
$newArray = array();
getValues($data);
function getValues($array){
global $newArray;
foreach ($array as $key => $value){
if(is_numeric($value['qty'])) {
$value['qty'] += intval($newArray[$key]['qty']);
$newArray[$key] = array('flag'=>$value['flag'],'qty'=>$value['qty']);
}
if (gettype($value) != 'array'){return;}
getValues($value);
}
}
ksort($newArray);
var_export($newArray);
Result:
array (
10001 =>
array (
'flag' => 'B',
'qty' => 2,
),
10002 =>
array (
'flag' => 'B',
'qty' => 1,
),
10003 =>
array (
'flag' => 'B',
'qty' => 2,
),
50001 =>
array (
'flag' => 'M',
'qty' => 1,
),
50002 =>
array (
'flag' => 'M',
'qty' => 1,
),
60002 =>
array (
'flag' => 'G',
'qty' => 1,
),
)
This seemed to work:
function extractArray(array $source, array &$destination, $originalIndex)
{
foreach($source as $index => $value)
{
if(is_array($value))
extractArray($value, $destination, $index);
else
$destination[$originalIndex][$index] = $value;
}
}
$test = array(
60002 => array
(
50001 => array
(
50002 => array
(
10001 => array
(
'flag' => 'B',
'qty' => 1
),
10002 => array
(
'flag' => 'B',
'qty' => 1
),
10003 => array
(
'flag' => 'B',
'qty' => 2
),
'flag' => 'M',
'qty' => 1
),
'flag' => 'M',
'qty' => 1
),
'flag' => 'G',
'qty' => 1
),
10001 => array
(
'flag' => 'B',
'qty' => 1
)
);
$new = array();
foreach($test as $index => $value)
extractArray($value, $new, $index);
var_dump($new);
die();
You can use a recursive approach to iterate over all levels of the array. For each item you check that it is an array and if it has any of the keys you want checked, add the array consisting of the found attributes.
function flattenArray($array, $keysToCheck) {
$result = array();
foreach($array as $item) {
// check if the current array item is a candidate to
// be added to the flattened array
if(is_array($item)) {
$foundAttributes = array();
foreach($item as $key=>$value) {
if(in_array($key, $keysToCheck) {
$foundAttributes[$key] = $value;
}
}
// we found at least one matching attribute
if(count($foundAttributes)) {
array_push($result, $foundAttributes);
}
// recursively go to the next level and merge the results from there
$result = array_merge($result, flattenArray($item, $keysToCheck);
}
}
return $result;
}
// usage example
$flattenedArray = flattenArray($originalArray, array('flag', 'qty'));
The above solution allows you to customise it for other type of objects, by passing different $keysToCheck arguments to the function.
If you also need the flattened array sorted, you can use usort() to achieve this.
Please pardon any syntax errors, I don't have a PHP interpreter at hand.

Sort php different format multidimensional array on key

I have an array like this
Array
(
[name] => Array
(
[0] => img/test240.jpg
[1] => img/cs1.jpg
[2] => img/cs2.jpg
[3] => img/cs3.jpg
)
[link] => Array
(
[0] => http://google.com
[1] => http://google.com
[2] => http://facebook.com
[3] => http://orkut.com
)
[order] => Array
(
[0] => 4
[1] => 1
[2] => 2
[3] => 3
)
)
I need to sort it by order WHICH IS KEY in Multidimensional array. Here is output.
Array
(
[name] => Array
(
[1] => img/cs1.jpg
[2] => img/cs2.jpg
[3] => img/cs3.jpg
[0] => img/test240.jpg
)
[link] => Array
(
[1] => http://google.com
[2] => http://facebook.com
[3] => http://orkut.com
[0] => http://google.com
)
[order] => Array
(
[1] => 1
[2] => 2
[3] => 3
[0] => 4
)
)
In this you can see when order is sorted name and link is also sorted according to the order. How can i do this with php.
You have to use array_map() in conjunction with sort().
If you want to preserve actual element order you have to use asort() instead sort().
Try this code:
$arr = array(
'name' => array(
0 => 'img/test240.jpg',
1 => 'img/cs1.jpg',
2 => 'img/cs2.jpg',
3 => 'img/cs3.jpg',
),
'link' => array(
0 => 'http://google.com',
1 => 'http://google.com',
2 => 'http://facebook.com',
3 => 'http://orkut.com',
),
'order' => array(
0 => 4,
1 => 1,
2 => 2,
3 => 3,
),
);
function mysort($a) {
asort($a);
return $a;
}
$arr = array_map('mysort', $arr);
print_r($arr);
Demo.
Try this, it uses array_multisort:
$array holds:
array (size=3)
'name' =>
array (size=4)
0 => string 'img/test240.jpg' (length=15)
1 => string 'img/cs1.jpg' (length=11)
2 => string 'img/cs2.jpg' (length=11)
3 => string 'img/cs3.jpg' (length=11)
'link' =>
array (size=4)
0 => string 'http://google.com' (length=17)
1 => string 'http://google.com' (length=17)
2 => string 'http://facebook.com' (length=19)
3 => string 'http://orkut.com' (length=16)
'order' =>
array (size=4)
0 => string '4' (length=1)
1 => string '1' (length=1)
2 => string '2' (length=1)
3 => string '3' (length=1)
Code:
$sort = array();
foreach($array as $k) {
foreach($k as $ind=>$val){
$sort['name'][$ind] = $array['name'][$ind];
$sort['link'][$ind] = $array['link'][$ind];
$sort['order'][$ind] = $array['order'][$ind];
}
}
array_multisort($sort['order'], SORT_ASC, $sort['link'], SORT_ASC, $sort['name'], SORT_ASC);
var_dump($sort);
Output:
array (size=3)
'name' =>
array (size=4)
0 => string 'img/cs1.jpg' (length=11)
1 => string 'img/cs2.jpg' (length=11)
2 => string 'img/cs3.jpg' (length=11)
3 => string 'img/test240.jpg' (length=15)
'link' =>
array (size=4)
0 => string 'http://google.com' (length=17)
1 => string 'http://facebook.com' (length=19)
2 => string 'http://orkut.com' (length=16)
3 => string 'http://google.com' (length=17)
'order' =>
array (size=4)
0 => string '1' (length=1)
1 => string '2' (length=1)
2 => string '3' (length=1)
3 => string '4' (length=1)
$this_arr = array(1,2,3,0);
function my_sort_2($arr, $arrangement)
{
$flag = false;
foreach($arr as $key => $val)
{
if(is_array($arr[$key]))
{
$arr[$key] = my_sort_2($arr[$key],$arrangement);
$flag = true;
}
}
if($flag == false && is_array($arr) && is_assoc($arr) === false)
{
$temp = array();
for($i = 0; $i < count($arrangement); $i++)
{
if(isset($arr[$arrangement[$i]]))
{
$temp[$arrangement[$i]] = $arr[$arrangement[$i]];
unset($arr[$arrangement[$i]]);
}
}
//$arr = array_merge($temp,$arr);
$arr = $temp;
}
return $arr;
}
Include this function below to run my own function. Also credit to #Matt Whittingham where i got this code from
function is_assoc($array)
{
$keys = array_keys($array);
return array_keys($keys) !== $keys;
}
Now let's do some sortin'... print_r(my_sort_2($arr,$this_arr)); assuming $arr contains Shan's array.
The output is EXACTLY what you desired.
It'll search for nested array (at least intended) and see if it's in a standard numeric ordered keys (in short, not custom order - yet; and not assoc) then sort it the way you want.
Note: I know my code isn't that probably good, optimized or bug free and that's my second attempt, misunderstanding your requirements first time (see the function name?).
Well after some research i found a simple solution like this
asort($data['order']);
$keys = array_keys($data['order']);
$data['name'] = array_replace(array_flip($keys), $data['name']);
$data['link'] = array_replace(array_flip($keys), $data['link']);
$data['order'] = array_replace(array_flip($keys), $data['order']);
Although i dont want to apply array_replace and array_flip on all the keys but this is done for the time being. I will surely trying to find how i can do it with single instruction.

Remove a value from an array and put that value into another array

i have two arrays and i need to extract the values of the 2nd array depending on the value of $arr[0]["num"]
$arr = array(
0 => array(
"id" => 24,
"num" => 2
),
1 => array(
"id" => 25,
"num" => 5
)
2 => array(
"id" => 26,
"num" => 3
)
);
$array = array('1','2','3','4','5','6','7','8','9','10');
$new = array();
foreach($arr as $key){
for($i=0;$i<$key['num'];$i++){
$new[$key['id']][$i] = $array[$i];
}
}
is it possible to remove the values of the 2nd array and transfer it into a new array?
what my loop does is just copying the values from the start after each loop. i want to remove the copied values from the 2nd array.
The output should be like this:
Array
(
[24] => Array
(
[0] => 1
[1] => 2
)
[25] => Array
(
[0] => 3
[1] => 4
[2] => 5
[3] => 6
[4] => 7
)
[26] => Array
(
[0] => 8
[1] => 9
[2] => 10
)
)
I'd suggest using array_shift
$arr = array(
array(
"id" => 24,
"num" => 2
),
array(
"id" => 25,
"num" => 5
),
array(
"id" => 26,
"num" => 3
)
);
$array = array('1','2','3','4','5','6','7','8','9','10');
$new = array();
foreach($arr as $key){
for($i=0;$i<$key['num'];$i++){
$new[$key['id']][$i] = $array[0]; // *1
array_shift($array);
}
}
echo '<pre>';
print_r($new);
*1 You have to change this line as well. Since array_shift removes the first array entry, each iteration should access array[0].
Output:
Array
(
[24] => Array
(
[0] => 1
[1] => 2
)
[25] => Array
(
[0] => 3
[1] => 4
[2] => 5
[3] => 6
[4] => 7
)
[26] => Array
(
[0] => 8
[1] => 9
[2] => 10
)
)
Try this
foreach($arr as $key){
for($i=0;$i<$key['num'];$i++){
$new[$key['id']][$i] = $array[$i];
// unset previous values, in first iteration it will remove 0, 1
unset($array[$i]);
}
// reset the array keys, so for loop $i will start from 0
$array = array_values($array);
}
Output:
array (size=3)
24 =>
array (size=2)
0 => string '1' (length=1)
1 => string '2' (length=1)
25 =>
array (size=5)
0 => string '3' (length=1)
1 => string '4' (length=1)
2 => string '5' (length=1)
3 => string '6' (length=1)
4 => string '7' (length=1)
26 =>
array (size=3)
0 => string '8' (length=1)
1 => string '9' (length=1)
2 => string '10' (length=2)

Categories