I need to re-arrange a php multidimensional array so that to 'match' corresponding values from different arrays;
this is my reproducible example
<?php
// my original array
$myar= array(
array('A'=>'xxx','B'=>1),
array('A'=>'yyy','B'=>2),
array('A'=>'xxx','B'=>3),
array('A'=>'yyy','B'=>4)
);
print_r($myar);
// my desired result, new array
$myar_new= array(
array('xxx'=>1,'yyy'=>2),
array('xxx'=>3,'yyy'=>4)
);
print_r($myar_new);
?>
any help for that?
thanks
If I got your logic right then this function is what you need.
(Edited)
function strange_reformat($srcArray) {
$newArray = [];
$c = count($srcArray);
$i = 0;
$groupStart = null;
$collect = [];
while($i < $c) {
$row = current($srcArray[$i]);
if ($row == $groupStart) {
$newArray[] = $collect;
$collect = [];
}
$tmp = array_values($srcArray[$i]);
$collect[] = [$tmp[0] => $tmp[1]];
if ($groupStart === null) $groupStart = $row;
$i++;
}
$newArray[] = $collect;
return $newArray;
}
print_r(strange_reformat($myar));
yes, that's it...
but now I need to generalise it, please consider this case
$myar= array(
array('A'=>'xxx','B'=>1),
array('A'=>'yyy','B'=>2),
array('A'=>'zzz','B'=>5),
array('A'=>'xxx','B'=>3),
array('A'=>'yyy','B'=>4),
array('A'=>'zzz','B'=>6)
);
function strange_reformat($srcArray) {
$newArray = [];
$c = count($srcArray);
for ($i=0; $i<$c; $i+=3) {
$first = array_values($srcArray[$i]);
$second = array_values($srcArray[$i+1]);
$third = array_values($srcArray[$i+2]);
$newArray[] = [$first[0]=>$first[1], $second[0]=>$second[1], $third[0]=>$third[1]];
}
return $newArray;
}
print_r(strange_reformat($myar));
Related
I want to combine two arrays into a dictionary.
The keys will be the distinct values of the first array, the values will be all values from the second array, at matching index positions of the key.
<?php
$a=[2,3,4,5,6,7,8,9,10];
$b=[1,1,3,2,1,2,6,8,8];
?>
array_combine($b,$a);
Expected result as
<?php
/*
Value '1' occurs at index 0, 1 and 4 in $b
Those indices map to values 2, 3 and 6 in $a
*/
$result=[1=>[2,3,6],3=>4,2=>[5,7],6=>8,8=>[9,10]];
?>
There are quite a few PHP array functions. I'm not aware of one that solves your specific problem. you might be able to use some combination of built in php array functions but it might take you a while to weed through your choices and put them together in the correct way. I would just write my own function.
Something like this:
function myCustomArrayFormatter($array1, $array2) {
$result = array();
$num_occurrences = array_count_values($array1);
foreach ($array1 AS $key => $var) {
if ($num_occurrences[$var] > 1) {
$result[$var][] = $array2[$key];
} else {
$result[$var] = $array2[$key];
}
}
return $result;
}
hope that helps.
$a=[2,3,4,5,6,7,8,9,10];
$b=[1,1,3,2,1,2,6,8,8];
$results = array();
for ($x = 0; $x < count($b); $x++) {
$index = $b[$x];
if(array_key_exists ($index, $results)){
$temp = $results[$index];
}else{
$temp = array();
}
$temp[] = $a[$x];
$results[$index] = $temp;
}
print_r($results);
Here's one way to do this:
$res = [];
foreach ($b as $b_index => $b_val) {
if (!empty($res[$b_val])) {
if (is_array($res[$b_val])) {
$res[$b_val][] = $a[$b_index];
} else {
$res[$b_val] = [$res[$b_val], $a[$b_index]];
}
} else {
$res[$b_val] = $a[$b_index];
}
}
var_dump($res);
UPDATE: another way to do this:
$val_to_index = array_combine($a, $b);
$result = [];
foreach ($val_to_index as $value => $index) {
if(empty($result[$index])){
$result[$index] = $value;
} else if(is_array($result[$index])){
$result[$index][] = $value;
} else {
$result[$index] = [$result[$index], $value];
}
}
var_dump($result);
I have 2 arrays in php
$array1[] = a,b,c,d,e;
$array2[] = 1,2,3,4,5;
$data = array('letter'=>$array1,'num'=>$array2);
return json_encode($data);
This will return:
[[a,b,c,d,e],[1,2,3,4,5]]
I'd like to return it in json_encode like this:
$data = [[1a,1],[b,2],[c,3],[d,4],[e,5]];
Can someone help me with this?
this is the simplest solution
$result = array();
foreach ($array1 as $k1 => $v1) {
$result[] = array($v1, $array2[$k1]);
}
echo json_encode($result)
but arrays must have the same length and same keys
Try below code, it is flexible and don't have to care about the length of the arrays.
<?php
$letters = array('a','b','c','d','e');
$numbers = array('1','2','3','4','5');
$counter = (sizeof($letters) > sizeof($numbers)) ? sizeof($letters) : sizeof($numbers);
$arr = array();
for($i=0; $i<$counter; $i++)
{
if(array_key_exists($i, $letters))
$arr[$i][] = $letters[$i];
if(array_key_exists($i, $numbers))
$arr[$i][] = $numbers[$i];
}
$json = json_encode($arr);
echo $json;
Output:
[["a","1"],["b","2"],["c","3"],["d","4"],["e","5"]]
Demo:
http://3v4l.org/7v7X4
What you are looking for is the function array_combine().
Here is an example:
$array1 = array("a","b","c","d","e");
$array2 = array(1,2,3,4,5);
$data = array_combine($array1, $array2);
$new_data = array();
foreach($data AS $key => $value) {
$new_data[] = array($key, $value);
}
print_r(json_encode($new_data));
Which should return something like:
[["a",1],["b",2],["c",3],["d",4],["e",5]]
UPDATE Changed the code to give the result wanted...
array one: 1,3,5,7
array two: 2,4,6,8
the array i want would be 1,2,3,4,5,6,7,8
I'm just using numbers as examples. If it was just numbers i could merge and sort but they will be words. So maybe something like
array one: bob,a,awesome
array two: is,really,dude
should read: bob is a really awesome dude
Not really sure how to do this. Does PHP have something like this built in?
You could write yourself a function like this:
function array_merge_alternating($array1, $array2) {
if(count($array1) != count($array2)) {
return false; // Arrays must be the same length
}
$mergedArray = array();
while(count($array1) > 0) {
$mergedArray[] = array_shift($array1);
$mergedArray[] = array_shift($array2);
}
return $mergedArray;
}
This function expects two arrays with equal length and merges their values.
If you don't need your values in alternating order you can use array_merge. array_merge will append the second array to the first and will not do what you ask.
Try this elegant solution
function array_alternate($array1, $array2)
{
$result = Array();
array_map(function($item1, $item2) use (&$result)
{
$result[] = $item1;
$result[] = $item2;
}, $array1, $array2);
return $result;
}
This solution works AND it doesn't matter if both arrays are different sizes/lengths:
function array_merge_alternating($array1, $array2)
{
$mergedArray = array();
while( count($array1) > 0 || count($array2) > 0 )
{
if ( count($array1) > 0 )
$mergedArray[] = array_shift($array1);
if ( count($array2) > 0 )
$mergedArray[] = array_shift($array2);
}
return $mergedArray;
}
Try this function:
function arrayMergeX()
{
$arrays = func_get_args();
$arrayCount = count($arrays);
if ( $arrayCount < 0 )
throw new ErrorException('No arguments passed!');
$resArr = array();
$maxLength = count($arrays[0]);
for ( $i=0; $i<$maxLength; $i+=($arrayCount-1) )
{
for ($j=0; $j<$arrayCount; $j++)
{
$resArr[] = $arrays[$j][$i];
}
}
return $resArr;
}
var_dump( arrayMergeX(array(1,3,5,7), array(2,4,6,8)) );
var_dump( arrayMergeX(array('You', 'very'), array('are', 'intelligent.')) );
var_dump( arrayMergeX() );
It works with variable numbers of arrays!
Live on codepad.org: http://codepad.org/c6ZuldEO
if arrays contains numeric values only, you can use merge and sort the array.
<?php
$a = array(1,3,5,7);
$b = array(2,4,6,8);
$merged_array = array_merge($a,$b);
sort($merged,SORT_ASC);
?>
else use this solution.
<?php
function my_merge($array1,$array2)
{
$newarray = array();
foreach($array1 as $key => $val)
{
$newarray[] = $val;
if(count($array2) > 0)
$newarray[] = array_shift($array2)
}
return $newarray;
}
?>
hope this help
Expects both arrays to have the same length:
$result = array();
foreach ($array1 as $i => $elem) {
array_push($result, $elem, $array2[$i]);
}
echo join(' ', $result);
I have an array and a var like this:
$arrPs =array('p1','p2','pN');
$intVar = 80;
Now i want to convert it into an array like this:
array(
'p1'=>array(
'p2'=>array(
'pN'=>$intVar
)
)
);
This should work no matter how many values are in $arrPs array.
Hope this makes sense.
/Sune
function myWalker($input, $last, &$output = array()) {
if (count($input) > 1) {
$val = array_shift($input);
$output[$val] = array();
myWalker($input, $last, $output[$val]);
}
else {
$output[$input[0]] = $last;
}
return $output;
}
$out = myWalker($arrPs, $intVar);
eval is good for this, use it with your own risk, and if the data is trustable
eval ('$rtn[\''.implode("']['", $arrPs).'\']='.$intVar.';');
var_dump($rtn);
I'd suggest something like this:
function buildNestedArrays($array, $initVar) {
$current = current($array);
$next = next($array);
if ($next === FALSE) {
return array($current => $initVar);
} else {
return array($current => buildNestedArrays($array, $initVar));
}
}
Usage:
reset($arrPs);
print_r(buildNestedArrays($arrPs, $intVar));
$arrPs = array('p1','p2','pN');
$intVar = 80;
$new_array = array();
$counter = 1;
for( $i = count($arrPs); $i >= 0; $i-- )
{
if( $counter==1)
{
$new_array = $intVar;
}
else
{
$new_array = array( $arrPs[$i] => $new_array);
}
$counter++;
}
print_r($new_array);
I have an array like the following:
array('category_name:', 'c1', 'types:', 't1')
I want the alternate values of an array to be the values of an array:
array('category_name:' => 'c1', 'types:' => 't1')
You could try: (untested)
$data = Array("category_name:","c1","types:","t1"); //your data goes here
for($i=0, $output = Array(), $max=sizeof($data); $i<$max; $i+=2) {
$key = $data[$i];
$value = $data[$i+1];
$output[$key] = $value;
}
Alternatively: (untested)
$output = Array();
foreach($data as $key => $value):
if($key % 2 > 0) { //every second item
$index = $data[$key-1];
$output[$index] = $value;
}
endforeach;
function fold($a) {
return $a
? array(array_shift($a) => array_shift($a))
+ fold($a)
: array();
}
print_r(fold(range('a','p' )));
~)
upd: a real-life version
function fold2($a) {
$r = array();
for($n = 1; $n < count($a); $n += 2)
$r[$a[$n - 1]] = $a[$n];
return $r;
}
Here is another yet complex solution:
$keys = array_intersect_key($arr, array_flip(range(0, count($arr)-1, 2)));
$values = array_intersect_key($arr, array_flip(range(1, count($arr)-1, 2)));
$arr = array_combine($keys, $values);
$array = your array;
$newArray['category_name:'] = $array[1];
$newArray['types:'] = $array[3];