Sort php different format multidimensional array on key - php

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.

Related

Sort multidimensonal array by version

Does anyone know how to correctly sort this array by version preserving the sub-arrays.
I have seen similar issues and solutions on stackoverflow but im not able to apply to my array.
Thanks in advance
array (size=3)
'1.23.006' =>
array (size=1)
0 => string '1' (length=1)
'2.0.0' =>
array (size=1)
0 => string '1' (length=1)
'10.0.0' =>
array (size=2)
0 => string '1' (length=1)
1 => string '4' (length=1)
I want it to be sorted like this:
array (size=3)
'10.0.0' =>
array (size=2)
0 => string '1' (length=1)
1 => string '4' (length=1)
'2.0.0' =>
array (size=1)
0 => string '1' (length=1)
'1.23.006' =>
array (size=1)
0 => string '1' (length=1)
You need to use uksort to sort your array by keys, with a custom function that calls version_compare to compare them:
$data = array('1.23.006' => array('1'), '2.0.0' => array('1'), '10.0.0' => array('1', '4'));
uksort($data, function ($a, $b) {
return version_compare($b, $a);
});
print_r($data);
Output:
Array
(
[10.0.0] => Array
(
[0] => 1
[1] => 4
)
[2.0.0] => Array
(
[0] => 1
)
[1.23.006] => Array
(
[0] => 1
)
)
Demo on 3v4l.org

Append an array to an existing array by index value?

I have an array like this:
Array (
[0] => 10060127
[1] => 10065127
[2] => 10070127
[3] => 10075127
)
I want to add an associative array based on the value in the array. e.g. find 10070127 and an an associative array to it containing various other info. Something like:
[1] => 10065127 => Time : 10:00
Date : 16/12/2014
Count : 1
How can I recognise the correct position and push these items to this array?
You can try this:
$dataArray = array(
0 => 10060127,
1 => 10065127,
2 => 10070127,
3 => 10075127
);
$toAdd = array(
1 => array(
10065127 => array("Time" => '10:00',
"Date" => '16/12/2014',
"Count" => '1'
)
),
2 => array(
10070127 => array("Time" => '17:25',
"Date" => '11/12/2014',
"Count" => '95'
)
)
);
foreach ($toAdd as $subArray) {
$toSearch = key($subArray);
$pos = array_search($toSearch, $dataArray);
if ($pos !== false) {
unset($dataArray[$pos]);
$dataArray[$toSearch] = $subArray[$toSearch];
}
}
var_dump ($dataArray);
Output will be:
array
0 => int 10060127
3 => int 10075127
10065127 =>
array
'Time' => string '10:00' (length=5)
'Date' => string '16/12/2014' (length=10)
'Count' => string '1' (length=1)
10070127 =>
array
'Time' => string '17:25' (length=5)
'Date' => string '11/12/2014' (length=10)
'Count' => string '95' (length=2)
Something like:
$id = '10070127';
$array[array_search($id, $array)] = array($id=>array(
'time'=>'10:00',
'Date'=>'16/12/2014',
'Count'=>1));

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)

removing parent array and pairing up its inner arrays values

here is my array
$array = Array
(
[0] => Array
(
[name] => crud_inputs[id]
[value] => id_Value
)
[1] => Array
(
[name] => crud_inputs[user_id][]
[value] => userid_Value
)
[2] => Array
(
[name] => crud_inputs[details]
[value] => details_value
)
)
i want to remove parent array ( $array ) and pair the
[name]=[value]
in each inner array
i want to end up with a
crud_inputs array
i.e
$crud_inputs[id] = id_Value ;
$crud_inputs[user_id][] = userid_Value ;
$crud_inputs[details] = details_value ;
-
I WANT TO BE ABLE TO DO SOMETHING LIKE THIS AT THE END
$MY_ORM->UPDATE( $table , $crud_inputs );
this is what i wrote so far but it doesn't work , i get a empty array at the end
$crud_inputs = array();
foreach($array as $ar )
{
$$ar['name'] = $ar['value'];
}
var_dump($crud_inputs);
#Wrikken , =========================================================
this is exactly what i get as my raw array
array (size=6)
0 =>
array (size=2)
'name' => string 'crud_inputs[id]' (length=15)
'value' => string 'id_Value' (length=8)
1 =>
array (size=2)
'name' => string 'crud_inputs[user_id][]' (length=22)
'value' => string 'userid_Value' (length=3)
2 =>
array (size=2)
'name' => string 'crud_inputs[user_id][]' (length=22)
'value' => string 'userid_Value2' (length=3)
3 =>
array (size=2)
'name' => string 'implode[user_id]' (length=16)
'value' => string ',' (length=1)
4 =>
array (size=2)
'name' => string 'crud_inputs[date]' (length=18)
'value' => string 'date_value' (length=13)
5 =>
array (size=2)
'name' => string 'crud_inputs[ip]' (length=15)
'value' => string 'ip_value' (length=13)
-
and this is how i handle it
$new = array();
foreach($array as $value){
$new[$value['name']] = $value['value'];
}
$item = $new;
var_dump($item);
This what was meant as a GET or POST array? parse_str helps:
$array = ...your array...
foreach($array as &$item){
$item = array_map('urlencode',$item);
$item = implode('=',$item);
}
$string = implode('&',$array);
parse_str($string,$result);
var_dump($result);
//and if I read the rest right:
foreach($result['implode'] as $key =>$value){
$result['crudinputs'][$key] = implode($value,$result['crudinputs'][$key]);
}
Earlier on:
Bad oneliner (your colleagues will hate you):
foreach($array as &$item){
$item = call_user_func_array('array_combine',call_user_func_array('array_merge_recursive',$item));
}
Readable multiliner (everybody happy):
foreach($array as &$item){
$new = array();
foreach($item as $value){
$new[$value['name']] = $value['value'];
}
$item = $new;
}
This is assuming an array with multiple items if I read your code correctly, so like:
Array
(
[0] => Array
(
[0] => Array
(
[name] => key0
[value] => value0
)
[1] => Array
(
[name] => key1
[value] => value1
)
[2] => Array
(
[name] => key2
[value] => value2
)
[3] => Array
(
[name] => key3
[value] => value3
)
)
[1] => Array
.... more items here
If not (you only have 1 item), you can omit the outer foreach loop in both examples.

How can I preserve multidimensional array information when performing array intersections in PHP?

I have many arrays containing an ID as the primary key, with multidimensional information under each id. Here are two examples:
First Example Array:
array
14181 =>
array
'industries' =>
array
'weight' => string '105652' (length=6)
'count' => string '11' (length=2)
48354 =>
array
'industries' =>
array
'weight' => string '508866' (length=6)
'count' => string '10' (length=2)
Second Example Array:
array
16434 =>
array
'business_types' =>
array
'weight' => string '104614' (length=6)
'count' => string '1' (length=1)
48354 =>
array
'business_types' =>
array
'weight' => string '103610' (length=6)
'count' => string '10' (length=2)
I'd like to get the intersection of many arrays like these ( based on the key ), but I need to preserve the weight and count data from each array for each key. Notice it's different weight and count data from each array. In this case, business_type and industries.
Final Array Needed:
array
48354 =>
array
'business_types' =>
array
'weight' => string '103610' (length=6)
'count' => string '10' (length=2)
'industries' =>
array
'weight' => string '508866' (length=6)
'count' => string '10' (length=2)
Originally I was not trying to keep the weights and counts, so I was simply performing an array_intersect_keys() and the job was done. Now I need to keep this data. I named the sub arrays different things in the hope that array_intersect_keys() would preserve it, however, it only preserves it for the first array in the function.
Is there a preferred way to do something like this?
The only solution I can come up with is to reduce all the arrays to a list of final ID's ( keys ) and then loop through that array pulling the weight and count info from each of the original arrays we compared.
Your proposed solution seems fine, but you might consider merging one list into the other, e.g.
<?php
$a1 = array(14181 => array('industries' => array('weight' => "105652", 'count' => "11")),
48354 => array('industries' => array('weight' => "508866", 'count' => "10")));
$a2 = array(16434 => array('business_types' => array('weight' => "104614", 'count' => "1")),
48354 => array('business_types' => array('weight' => "103610", 'count' => "10")));
//print_r($a1);
//print_r($a2);
foreach($a2 as $a2k => $a2v)
{
// The loop below should only go through once, but if there are multiple types it will be ok
foreach($a2v as $a2vk => $a2vv)
{
$a1[$a2k][$a2vk] = $a2vv;
}
}
printf("Output:\n");
print_r($a1);
printf("Output:\n");
print_r($a1);
Output:
Output:
Array
(
[14181] => Array
(
[industries] => Array
(
[weight] => 105652
[count] => 11
)
)
[48354] => Array
(
[industries] => Array
(
[weight] => 508866
[count] => 10
)
[business_types] => Array
(
[weight] => 103610
[count] => 10
)
)
[16434] => Array
(
[business_types] => Array
(
[weight] => 104614
[count] => 1
)
)
)
I believe that this will be slightly faster than your proposed solution.
Edit: The above was an array merge type algorithm that would merge the arrays even if a key wasn't common among the arrays. The algorithm below will only produce the intersection of the two arrays. My fault in initially getting the question:
<?php
$a1 = array(14181 => array('industries' => array('weight' => "105652", 'count' => "11")),
48354 => array('industries' => array('weight' => "508866", 'count' => "10")));
$a2 = array(16434 => array('business_types' => array('weight' => "104614", 'count' => "1")),
48354 => array('business_types' => array('weight' => "103610", 'count' => "10")));
//print_r($a1);
//print_r($a2);
// Pass the smaller array as first argument
if(count($a1) <= count($a2))
{
$res = my_merge($a1, $a2);
}
else
{
$res = my_merge($a2, $a1);
}
function my_merge($a1, $a2)
{
$res = array();
foreach($a1 as $a1k => $a1v)
{
if(array_key_exists($a1k, $a2))
{
$res[$a1k] = array_merge($a1[$a1k], $a2[$a1k]);
}
}
return $res;
}
printf("Output:\n");
print_r($res);
Output:
Array
(
[48354] => Array
(
[industries] => Array
(
[weight] => 508866
[count] => 10
)
[business_types] => Array
(
[weight] => 103610
[count] => 10
)
)
)

Categories