How to reformatted array - php

I have an array with indexes like
$array = array(
"first_name" => "test",
"last_name" => "testsurename"
);
I need to convert it to:
$array = array(
"0" => array("first_name" => "test"),
"1" => array("last_name" => "testsurename")
);

try this,
$array = array("first_name"=>"test","last_name"=>"testsurename");
$newarray = array();
foreach($array as $key=> $val)
{
$newarray[][$key] = $val;
}
print_r($newarray);
OUTPUT :
$array = array(
"0" => array("first_name" => "test"),
"1" => array("last_name" => "testsurename")
);
DEMO

Another way is to use array_walk, but basically it's all the same.
$array = array("first_name"=>"test","last_name"=>"testsurename");
$result = array();
array_walk($array,
function(&$item, $key, $target) { $target[] = array($key => $item); },
&$result);

You can try
<?php
$array = array("first_name"=>"test","last_name"=>"testsurename");
$final_array = [];
foreach ($array as $key => $value) {
array_push($final_array, [$key => $value]);
}
print_r($final_array);
Output
Array ( [0] => Array ( [first_name] => test ) [1] => Array ( [last_name] => testsurename ) )

$inputArray = [
"first_name" => "test",
"last_name" => "testsurename"
];
$outputArray = array_reduce(array_keys($inputArray), function($carry, $key) use ($inputArray) {
$carry[][$key] = $array[$key];
return $carry;
}, []);
/**
result will be for $outputArray
[
["first_name" => "test"],
["last_name" => "testsurename"]
];
**/

Related

How to create dynamic combination with php?

I have 3 array like
$arr = [
"color" => [["name"=>"red"]],
"size" => [["name"=>"18 inch"], ["name"=>"15 inch"]],
"type" => [["name"=>"plastic"]]
]
$combo = array();
foreach ($arr['size'] as $size) {
foreach($arr['color'] as $color){
foreach ($arr['type'] as $type) {
$variant = json_encode(['size' => $size->name, 'color' =>
$color->name, 'type' => $type->name]);
array_push($combo,$variant);
}
}
}
echo $combo;
// result
0 => "{"size":"15 inch","color":"yellow","type":"metal"}"
1 => "{"size":"18 inch","color":"yellow","type":"plastic"}"
It works properly but but there is can be less or more variants. How can I handle this.
For example
$arr = [
"size" => [["name"=>"18 inch"], ["name"=>"15 inch"]],
"type" => [["name"=>"plastic"]]
]
Or
$arr = [
"color" => [["name"=>"red"]],
"size" => [["name"=>"18 inch"], ["name"=>"15 inch"]],
"type" => [["name"=>"plastic"]],
"brand" => [['name' => 'something']],
]
For what i understand, you have to combine the arrays of properties into one array of
object.
I have to leave now, but if you need a explanation leave a comment and i updated the answers
$arr = [
"color" => [["name"=>"red"],['name'=>'yellow']],
"size" => [["name"=>"18 inch"], ["name"=>"15 inch"]],
"type" => [["name"=>"plastic"]],
"brand" => [['name' => 'something']],
];
function runFor($arr ,&$array, $keys,$index,&$positions){
foreach ($arr[$keys[$index]] as $key => $espec){
$positions[$keys[$index]] = $key;
if($index + 1 < count($keys)){
runFor($arr,$array,$keys, $index+1,$positions);
}else{
$item = (object)[];
foreach ($keys as $key){
$item->$key = $arr[$key][$positions[$key]]['name'];
}
array_push($array,$item);
}
unset($positions[$keys[$index]]);
}
}
$array = array();
$keys = array_keys($arr);
$positions = [];
runFor($arr,$array,$keys,0,$positions);
$combo = array();
foreach ($array as $item){
array_push($combo,json_encode($item));
}
var_dump($combo);

How to expand an array based on quantity

I have an array which stores quantity. I want to convert this into individual array as described below
What i have tried
function expandArray($TICKETTYPE_TEMPARRAY, $readQuantity){
for($i=1; $i<=$readQuantity; $i++){
$TICKETTYPE[] = $TICKETTYPE_TEMPARRAY;
}
}
foreach($TICKETTYPE_TEMPARRAY as $key => $value){
$readQuantity = $value["QUANTITY"];
expandArray($TICKETTYPE_TEMPARRAY, $readQuantity);
}
My array
$myarray = array(
"TICKETPRICE" => "6.0000",
"QUANTITY" => "2",
"COUNTRYID" => "15"
)
Expected output:
[{TICKETPRICE:6.000, QUANTITY:2, COUNTRYID=15},
{TICKETPRICE:6.000, QUANTITY:2, COUNTRYID=15}]
I think you want something like this:
$myarray = array(array(
"TICKETPRICE" => "6.0000",
"QUANTITY" => "2",
"COUNTRYID" => "15"
),
array(
"TICKETPRICE" => "4.0000",
"QUANTITY" => "3",
"COUNTRYID" => "9"
));
$output = array();
foreach ($myarray as $array) {
$output[] = array_fill(0, $array['QUANTITY'], $array);
}
echo json_encode($output);
Output:
[[{"TICKETPRICE":"6.0000","QUANTITY":"2","COUNTRYID":"15"},
{"TICKETPRICE":"6.0000","QUANTITY":"2","COUNTRYID":"15"}
],
[{"TICKETPRICE":"4.0000","QUANTITY":"3","COUNTRYID":"9"},
{"TICKETPRICE":"4.0000","QUANTITY":"3","COUNTRYID":"9"},
{"TICKETPRICE":"4.0000","QUANTITY":"3","COUNTRYID":"9"}
]]
Or if you want a completely flat array:
$output = array();
foreach ($myarray as $array) {
$output = array_merge($output, array_fill(0, $array['QUANTITY'], $array));
}
echo json_encode($output);
Output:
[{"TICKETPRICE":"6.0000","QUANTITY":"2","COUNTRYID":"15"},
{"TICKETPRICE":"6.0000","QUANTITY":"2","COUNTRYID":"15"}
{"TICKETPRICE":"4.0000","QUANTITY":"3","COUNTRYID":"9"},
{"TICKETPRICE":"4.0000","QUANTITY":"3","COUNTRYID":"9"},
{"TICKETPRICE":"4.0000","QUANTITY":"3","COUNTRYID":"9"}
]
Demo on 3v4l.org
Simply array_fill and json_encode may help you.
<?php
$myarray = array(
"TICKETPRICE" => "6.0000",
"QUANTITY" => "2",
"COUNTRYID" => "15"
);
$myarray = json_encode(array_fill(0, $myarray['QUANTITY'], $myarray));
print '<pre>';
print_r($myarray);
?>

PHP: Link address of multiple array keys into another bigger array

I want to combine 3 small arrays that have unique keys between them into 1 big array but when I modify a value in the big array I want it also to reflect in the corresponding small array.
For example I have these 3 small arrays:
$arr1 = ['key1' => 'data1', 'key2' => 'data2'];
$arr2 = ['key3' => 'data3', 'key4' => 'data4', 'key5' => 'data5'];
$arr3 = ['key6' => 'data6'];
I want to have a $bigArray that has each key's address linked/mapped to each value of the small arrays. So if I do something like:
$bigArray['key4'] = 'something else';
then it would modify $arr2['key4'] to the same value ('something else').
If I try something like:
$bigArray = [&$arr1, &$arr2, &$arr3];
It has the unfortunate effect of making a multidimensional array with the keys to the values mapped.
Two ways i found
<?php
error_reporting(E_ALL);
$arr1 = ['key1' => 'data1', 'key2' => 'data2'];
$arr2 = ['key3' => 'data3', 'key4' => 'data4', 'key5' => 'data5'];
$arr3 = ['key6' => 'data6'];
$big = [];
if (true) {
foreach (['arr1', 'arr2', 'arr3'] as $v) {
foreach (array_keys($$v) as $k) {
$big[$k] = &${$v}[$k];
}
}
}
else {
foreach ([&$arr1, &$arr2, &$arr3] as &$v) {
foreach (array_keys($v) as $k) {
$big[$k] = &$v[$k];
}
}
}
$big['key1'] = 'data1mod';
print_r($big);
print_r($arr1);
3rd way with function
$big = [];
$bindToBig = function (&$a) use (&$big) {
foreach (array_keys($a) as $k) {
$big[$k] = &$a[$k];
}
};
$bindToBig($arr1);
$bindToBig($arr2);
$bindToBig($arr3);
You can't bind data that way, but you can link them in the same object:
class ArrayLink {
public $bigArray;
public $linkedChildrenArray;
protected $childrenArray;
public function __construct( $childrenArray ) {
$this->childrenArray = $childrenArray;
}
public function changeValueForKey( $arrKey, $arrValue ) {
foreach ( $this->childrenArray as $key => $value ) {
foreach ( $value as $subKey => $subValue ) {
if ( $arrKey == $subKey ) {
$this->bigArray[ $subKey ] = $arrValue;
$this->childrenArray[ $key ][ $subKey ] = $arrValue;
}
}
}
$this->linkedChildrenArray = (object) $this->childrenArray;
}
}
As you can see, the $arr2 now need to be access from $arrayLink object:
$arr1 = [ 'key1' => 'data1', 'key2' => 'data2' ];
$arr2 = [ 'key3' => 'data3', 'key4' => 'data4', 'key5' => 'data5' ];
$arr3 = [ 'key6' => 'data6' ];
$arrayLink = new ArrayLink( array( 'arr1' => $arr1, 'arr2' => $arr2, 'arr3' => $arr3 ) );
$arrayLink->changeValueForKey( 'key3', 'new value for key 3' );
echo $arrayLink->bigArray['key3']; //new value for key 3
echo $arrayLink->linkedChildrenArray->arr2['key3']; //new value for key 3

merge two associative arrays add titles

I have two arrays
$Array_1 = array(
'ID_1' => 'Michael',
'ID_2' => 'Jerry',
'ID_3' => 'Tony',
'ID_4' => 'Roger',
);
$Array_2 = array(
'ID_1' => 'Chef',
'ID_2' => 'Mechanic',
'ID_3' => 'Cook',
'ID_4' => 'Dealer',
);
I wish to merge them on the ID column and have my final array be in this form
$employees = array(
array(
'name' => 'Jason',
'occupation' => 'Chef'
),
array(
'name' => 'Mike',
'occupation' => 'Mechanic'
),
...
);
I know I can array combine them like below:
$new_array = array_combine(array_values($Array_1), array_values($Array_2));
but how would I add the titles "Name": and "Occupation":
Can you try this,
$Employees = array();
foreach($Array_1 as $key=>$value):
$Employees['Employees'][] = array('Name'=>$value, 'Occupation'=>$Array_2[$key]);
endforeach;
echo "<pre>";
print_r($Employees);
echo "</pre>";
echo json_encode($Employees);
OP:
{"Employees":[{"Name":"Jason","Occupation":"Chef"}, {"Name":"Mike","Occupation":"Mechanic"}]}
i dont know how the array look. but you can try my two solution
First solution
$array1 = array("id" => array("id1", "id2", "id3"), "names" => array("name1", "name2", "name3"));
$array2 = array("id" => array("id1", "id2", "id3"), "occupation" => array("occupation1", "occupation2", "occupation3"));
$filter_array = array("employees" => array());
foreach ($array1["id"] as $index => $key) {
$employee = array();
$occupation = in_array($key, $array2["id"]) ? $array2["occupation"][$index] : false;
if ($occupation === false) {
continue;
}
$employee["name"] = $key;
$employee["occupation"] = $occupation;
array_push($filter_array["employees"], $employee);
}
echo "<pre>" . print_r($filter_array, true) . "</pre>";
Second Solution
$array1 = array("id1" => array("names" => "name1"), "id2" => array("names" => "name2"), "id3" => array("names" => "name3"));
$array2 = array("id1" => array("occupation" => "occupation1"), "id2" => array("occupation" => "occupation2"), "id3" => array("occupation" => "occupation3"));
$filter_array = array("employees" => array());
foreach ($array1 as $key => $value) {
$employee = array();
if (!isset($array2[$key])) {
continue;
}
$employee["name"] = $value["names"];
$employee["occupation"] = $array2[$key]["occupation"];
array_push($filter_array["employees"], $employee);
}
echo "<pre>" . print_r($filter_array, true) . "</pre>";
i hope my code can help.
you can try this
$Array_1 = array(
'ID_1' => 'Michael',
'ID_2' => 'Jerry',
'ID_3' => 'Tony',
'ID_4' => 'Roger',
);
$Array_2 = array(
'ID_1' => 'Chef',
'ID_2' => 'Mechanic',
'ID_3' => 'Cook',
'ID_4' => 'Dealer',
);
$filter_array = array("employees" => array());
foreach($Array_1 as $key => $value){
$employee = array();
if(!isset($Array_2[$key])){ continue; }
$employee["name"] = $value;
$employee["occupation"] = $Array_2[$key];
array_push($filter_array["employees"], $employee);
}
EDIT 2
Aah, now I see the phpfiddle in the comments and the edit to the OP. So, the ID is already the key of the array? ... Then just do
foreach($Array_1 as $key_1 => $value_1) {
$new_Array[$key_1]['Names'] = $Array_1['Names'];
}
foreach($Array_2 as $key_2 => $value_2) {
$new_Array[$key_2]['Occupation'] = $Array_2['Occupation'];
}
use array_walk . It runs a function per each array item .combine them in the function .

Run throw array of associative array and find keys

I have two arrays that look like this:
(this one is ordered by value_max)
$max_values = [
["name" => "john", "id" => 5, "value_max" => 500],
["name" => "john", "id" => 3, "value_max" => 200],
...
];
$min_values = [
["name" => "john", "id" => 5, "value_min" => 100],
["name" => "john", "id" => 3, "value_min" => 150],
...
];
And I need to have a final array like this:
(This one stills need to be ordered by value_max, so I assume I could just overwrite the first array with the calculations done with the second)
$max_and_difference_values = [
["name" => "john", "id" => 5, "value_max" => 500, "difference_value" => 400],
["name" => "john", "id" => 3, "value_max" => 200, "difference_value" => 50 ],
...
];
My question is pretty straight: What is the best/effective way to run through both first arrays and build the last one. Assuming that the size of the arrays can be of around 150 elements.
To avoid looping through all arrays repeatedly, index one array by the field you want to merge on, i.e. the 'id' key:
$second = array_combine(array_map(function ($i) { return $i['id']; }, $second_array), $second_array);
Then looping through the other and comparing the values is pretty easy:
$third = array();
foreach ($first_array as $i) {
$third[] = $i + array('difference_value' => $i['value_max'] - $second[$i['id']]['value_min']);
}
If it's guaranteed that both arrays will have exactly matching keys, you don't even need the first step and just go by already existing keys.
This will sort your array. So you can sort the second array.
<?php
$min_values = array(
array("name" => "john", "id" => 5, "value_min" => 100),
array("name" => "john", "id" => 3, "value_min" => 150),
);
function aasort (&$array, $key) {
$sorter=array();
$ret=array();
reset($array);
foreach ($array as $ii => $va) {
$sorter[$ii]=$va[$key];
}
asort($sorter);
foreach ($sorter as $ii => $va) {
$ret[$ii]=$array[$ii];
}
$array=$ret;
}
aasort($min_values,"id");
echo "<pre>";
print_r($min_values);
echo "</pre>";
?>
And then you can use the logic what Alessandro Minoccheri mentioned.
$arr = array();
for ($i=0; $i<count($first_array);$i++){
$arr['name'] = $first_array[$i]['name'];
$arr['id'] = $first_array[$i]['id'];
$arr['value_max'] = $first_array[$i]['value_max'];
$arr['difference_value'] = $first_array[$i]['value_max']-$second[$i['id']]['value_max'] ;
}
As you have not shared how the second array with the minimum values is ordered (in itself and relative to the maximum values array), I'd say, index the minimum values by the id entry and then do the calculation in a second iteration. It should be fast enough, 150 elements is just "nothing":
$max_values = [
["name" => "john", "id" => 5, "value_max" => 500],
["name" => "john", "id" => 3, "value_max" => 200],
];
$min_values = [
["name" => "john", "id" => 5, "value_min" => 100],
["name" => "john", "id" => 3, "value_min" => 150],
];
$min_values_by_id = [];
foreach($min_values as $min) {
$min_values_by_id[$min['id']] = $min['value_min'];
}
$max_and_difference_values = $max_values;
foreach($max_and_difference_values as &$entry)
{
$entry['difference_value'] = $entry['value_max'] - $min_values_by_id[$entry['id']];
}
unset($entry);
print_r($max_and_difference_values);
This is just a straight forward example, nothing fancy. Demo
the following works for me. I'm not a PHP expert though, i.e. I'm not so familiar with cloning (note the empty clone array). Note that it only copies existing properties (if one array does contain a min_value and another does only contain a some other key)
In essence
function convertArr( $arr ) {
// Easy referencing without having to search through the arrays more than once for a matching id
$new_arr = array();
foreach( $arr as $array ) {
$new_arr[ $array['id'] ] = cloneArr( $array );
}
return $new_arr;
}
function merge( $arr1, $arr2 ) {
$convertedArr1 = convertArr( $arr1 );
$convertedArr2 = convertArr( $arr2 );
$arr = array();
// Based on the ordered array
foreach( $convertedArr1 as $array ) {
$id = $array['id'];
$tempArr = array();
foreach( $convertedArr1[ $id ] as $k => $v ) {
$tempArr[ $k ] = $v;
}
foreach( $convertedArr2[ $id ] as $k => $v ) {
$tempArr[ $k ] = $v;
}
array_push( $arr, $tempArr );
}
return $arr;
}
Full example:
<?php
//$arr1 = [ ["name" => "john", "id" => 5, "value_max" => 500], ["name" => "john", "id" => 3, "value_max" => 200] ];
//$arr2 = [ ["name" => "john", "id" => 5, "value_min" => 100], ["name" => "john", "id" => 3, "value_min" => 150] ];
$arr1 = array(
array( "name" => "john", "id" => 5, "value_max" => 500 ),
array( "name" => "john", "id" => 3, "value_max" => 200 )
);
$arr2 = array(
array( "name" => "john", "id" => 5, "value_min" => 100 ),
array( "name" => "john", "id" => 3, "value_min" => 150 )
);
function neatPrint( $arr ) {
echo "<pre>";
print_r( $arr );
echo "</pre>";
}
echo "<h2>Before</h2>";
neatPrint( $arr1 );
neatPrint( $arr2 );
echo "<hr/>";
function cloneArr( $old ) {
// I dunno how to properly clone
return $old;
}
function convertArr( $arr ) {
// Easy referencing without having to search through the arrays more than once for a matching id
$new_arr = array();
foreach( $arr as $array ) {
$new_arr[ $array['id'] ] = cloneArr( $array );
}
return $new_arr;
}
function merge( $arr1, $arr2 ) {
$convertedArr1 = convertArr( $arr1 );
$convertedArr2 = convertArr( $arr2 );
$arr = array();
// Based on the ordered array
foreach( $convertedArr1 as $array ) {
$id = $array['id'];
$tempArr = array();
neatPrint( $convertedArr1[ $id ] );
neatPrint( $convertedArr2[ $id ] );
foreach( $convertedArr1[ $id ] as $k => $v ) {
$tempArr[ $k ] = $v;
}
foreach( $convertedArr2[ $id ] as $k => $v ) {
$tempArr[ $k ] = $v;
}
array_push( $arr, $tempArr );
}
echo "<h2>Result</h2>";
return $arr;
}
echo "<h2>Loopthrough</h2>";
neatPrint( merge( $arr1, $arr2 ) );
?>
Let me know what you think :-)
if the element are in order try this code:
$arr = array();
for ($i=0; $i<count($first_array);$i++){
$arr['name'] = $first_array[$i]['name'];
$arr['id'] = $first_array[$i]['id'];
$arr['value_max'] = $first_array[$i]['value_max'];
$arr['difference_value'] = $first_array[$i]['value_max']-$second[$i['id']]['value_max'] ;
}

Categories