PHP format an array of arrays into a flat array - php

I have an generated array into this format and want to generated a second array to fit into a file that expects the specific format
This is the array i have :
(int) 0 => array(
[Service] => Array
(
[id] => 6948229
[document] => Array
(
[number] => 0003928425
)
)
This is the array i want to build from the previous array (will have many indexes)
verified[id]
verified[number]
So far i build this script:
foreach($data as $key=>$value )
{
echo '<br>key '.$key;
foreach($value as $k=>$v)
{
$Verified[$key]['id'] = $v["id"];
$Verified[$key]['number'] = $v['document']['number'];
But just get undefined index error message.
Which indexes i must use to get the flatten array ?

From what I can make from your question, you can do something like this to get the desired output,
$Verified = []; //use array() for versions below 5.5
foreach($data as $key=>$value )
{
echo '<br>key '.$key;
foreach($value as $k=>$v)
{
if(is_array($v)){
$Verified[$key]['number'] = $v['document']['number'];
}
$Verified[$key]['id'] = $v['id'];

Please pass your array to this function
function arrayconvert($arr) {
if (is_array($arr)) {
foreach($arr as $k => $v) {
if (is_array($v)) {
arrayconvert($v);
} else {
$newarr[$k] = $v;
}
}
}
return $newarr;
}

There is no need of second foreach and you are getting undefined index because you are using $v['id'] insted of $val['id'] in that line $Verified[$key]['id'] = $v["id"];
<?php
$data = array('Service' => array('id' => 6948229,'document' => array ('number' => '0003928425' )));
$verified = array();
foreach($data as $key => $val)
{
$verified[$key]['id'] = $val['id'];
$verified[$key]['number'] = $val['document']['number'];
}
echo "<pre>"; print_r($verified);
?>
output
Array
(
[Service] => Array
(
[id] => 6948229
[number] => 0003928425
)
)

Related

How can I sort values from an existing array by data type?

I try to determine the data type of each array value from an existing array using foreach() and var_dump().
Let's say I have this array: example:
$arr = ['this','is', 1, 'array', 'for', 1, 'example'];
Now I have to take each value of this field and determine its data type.
I try this:
$str = array();
$int = array();
foreach($arr as $k => $val) {
if(var_dump($arr[$k]) == 'string'){
$str[] = $arr[$k];
} else {
$int[] = $arr[$k];
}
}
In other words, I try to sort the values from an existing array by data type and create a new array with only 'string' values and a second new array with only 'int' values. But it seems that my 'if' condition isn't working properly. How else could I solve this please? Thank you.
You need to use gettype to get the type of a value, not var_dump:
foreach($arr as $k => $val) {
if(gettype($arr[$k]) == 'string'){
$str[] = $arr[$k];
} else {
$int[] = $arr[$k];
}
}
Output:
Array
(
[0] => this
[1] => is
[2] => array
[3] => for
[4] => example
)
Array
(
[0] => 1
[1] => 1
)
Demo on 3v4l.org
Use gettype
$data = array('this','is', 1, 'array', 'for', 1, 'example');
foreach ($data as $value) {
echo gettype($value), "\n";
}

How to parse arrays with different levels PHP

In a foreach loop i would like to compare [name] value beetween different arrays but they have not the same levels.
Array(
[array1] => Array
(
[0] => WP_Term Object
(
[name] => Plafond
)
)
[array2] => WP_Term Object
(
[name] => Chaudière
)
[array3] => Array
(
[0] => WP_Term Object
(
[name] => Pla
)
[1] => WP_Term Object
(
[name] => Toc
)
)
)
I don't know how could i get the [name] in the same loop whereas levels are different.
I have tried to make :
foreach( $fields as $name => $value )
{
echo $value->name; }
Should i add another loop in the first loop ?
thanks
So your data looks like this:
$json = '{"array1":[{"name":"Plafond"}],"array2":{"name":"Chaudière"},"array3":[{"name":"Pla"},{"name":"Toc"}]}';
$array = json_decode($json);
If you don't know how deep it will go, a simple recursive function should work. Perhaps something like this:
function get_name($o, &$output) {
if (is_array($o)) {
foreach($o as $v) {
get_name($v, $output);
}
} elseif (property_exists($o, "name")) {
$output[] = $o->name;
}
}
$output = [];
foreach ($array as $v) {
get_name($v, $output);
}
If you data is going to look like the sample you provided (i.e. it will always be first or second level) then you don't need to worry about recursion.
$output = [];
foreach ($array as $k=>$v) {
if (is_array($v)) {
foreach ($v as $k2=>$v2) {
$output[] = $v2->name;
}
} else {
$output[] = $v->name;
}
}
Either way, your output values are all in the $output array:
print_r($output);
Output:
Array
(
[0] => Plafond
[1] => Chaudière
[2] => Pla
[3] => Toc
)
You can use array_map, array_key_exists to retrive the name index from the array
$jsonFormat = '{"array1":[{"name":"Plafond"}],"array2":{"name":"Chaudière"},"array3":[{"name":"Pla"},{"name":"Toc"}]}';
$jsonArray = json_decode($jsonFormat,true);
$res = [];
array_map(function($v) use (&$res){
if(array_key_exists('name', $v)){
$res[] = $v['name'];
}else{
foreach($v as $_key => $_value){
$res[] = $_value['name'];
}
}
}, $jsonArray);
echo '<pre>';
print_r($res);
Result:-
Array
(
[0] => Plafond
[1] => Chaudière
[2] => Pla
[3] => Toc
)
You can use $res to compare the names.

Don't want Array ito combine values

I Have an array in PHP that looks like:
Array ( [2099:360] => 6-3.25 [2130:361] => 4-2.5 [2099:362] => 14-8.75 )
Notice there is Two Keys that are 2099 and one that is 2130. I Have a foreach to remove the everything after the colon. the $drop is my array
$a = array();
foreach ($drop as $part=>$drop_a){
$ex_part = explode(":", $part);
$a[$ex_part[0]] = $drop_a;
}
print_r($a);
but when I print $a it displays only the recent value of the 2099?
Array ( [2099] => 14-8.75 [2130] => 4-2.5 )
Any Successions? How can I get it to display all of the values?
Thank You for Your Help
One solution is to use a multi-dimensional array to store this strategy:
$a = array();
foreach ($drop as $part=>$drop_a){
$ex_part = explode(":", $part);
if (isset($a[$ex_part[0]])) {
$a[$ex_part[0]][] = $drop_a;
} else {
$a[$ex_part[0]] = array($drop_a);
}
}
Your resulting data-set will however be different:
Array ( [2099] => Array ( [0] => 6-3.25 [1] => 14-8.75) [2130] => Array ( [0] => 4-2.5 ) )
It may be beneficial to you to preserve the second portion after the colon :
$a = array();
foreach ($drop as $part=>$drop_a){
$ex_part = explode(":", $part);
if (isset($a[$ex_part[0]])) {
$a[$ex_part[0]][$ex_part[1]] = $drop_a;
} else {
$a[$ex_part[0]] = array($ex_part[1] => $drop_a);
}
}
Now your result is a little more meaningful:
Array ( [2099] => Array ( [360] => 6-3.25 [362] => 14-8.75) [2130] => Array ( [361] => 4-2.5 ) )
Finally you can use alternative key-naming strategy if one is already occupied:
$a = array();
foreach ($drop as $part=>$drop_a){
$ex_part = explode(":", $part);
if (isset($a[$ex_part[0]])) {
$a[altName($ex_part[0], $a)] = $drop_a;
} else {
$a[$ex_part[0]] = $drop_a;
}
}
function altName($key, $array) {
$key++; // Or however you want to do an alternative naming strategy
if (isset($array[$key])) {
return altName($key, $array); // This will eventually resolve - but be careful with the recursion
}
return $key;
}
Returns:
Array
(
[2099] => 6-3.25
[2130] => 4-2.5
[2100] => 14-8.75
)
You basically have a key and a sub key for each entry, so just put them in a multidimensional array:
$a = array();
foreach ($drop as $key => $val) {
list($key, $subKey) = explode(':', $key);
$a[$key][$subKey] = $val;
}
Gives you:
Array
(
[2099] => Array
(
[360] => 6-3.25
[362] => 14-8.75
)
[2130] => Array
(
[361] => 4-2.5
)
)
You can traverse multidimensional arrays by nesting loops:
foreach ($a as $key => $subKeys) {
foreach ($subKeys as $subKey => $val) {
echo "$key contains $subKey (value of $val) <br>";
}
}

Replace key of array with the value of another array while looping through

I have two multidimensional arrays. First one $properties contains english names and their values. My second array contains the translations. An example
$properties[] = array(array("Floor"=>"5qm"));
$properties[] = array(array("Height"=>"10m"));
$translations[] = array(array("Floor"=>"Boden"));
$translations[] = array(array("Height"=>"Höhe"));
(They are multidimensional because the contains more elements, but they shouldn't matter now)
Now I want to translate this Array, so that I its at the end like this:
$properties[] = array(array("Boden"=>"5qm"));
$properties[] = array(array("Höhe"=>"10m"));
I have managed to build the foreach construct to loop through these arrays, but at the end it is not translated, the problem is, how I tell the array to replace the key with the value.
What I have done is this:
//Translate Array
foreach ($properties as $PropertyArray) {
//need second foreach because multidimensional array
foreach ($PropertyArray as $P_KiviPropertyNameKey => $P_PropertyValue) {
foreach ($translations as $TranslationArray) {
//same as above
foreach ($TranslationArray as $T_KiviTranslationPropertyKey => $T_KiviTranslationValue) {
if ($P_KiviPropertyNameKey == $T_KiviTranslationPropertyKey) {
//Name found, save new array key
$P_KiviPropertyNameKey = $T_KiviTranslationValue;
}
}
}
}
}
The problem is with the line where to save the new key:
$P_KiviPropertyNameKey = $T_KiviTranslationValue;
I know this part is executed correctly and contains the correct variables, but I believe this is the false way to assing the new key.
This is the way it should be done:
$properties[$oldkey] = $translations[$newkey];
So I tried this one:
$PropertyArray[$P_KiviPropertyNameKey] = $TranslationArray[$T_KiviTranslationPropertyKey];
As far as I understood, the above line should change the P_KiviPropertyNameKey of the PropertyArray into the value of Translation Array but I do not receive any error nor is the name translated. How should this be done correctly?
Thank you for any help!
Additional info
This is a live example of the properties array
Array
(
[0] => Array
(
[country_id] => 4402
)
[1] => Array
(
[iv_person_phone] => 03-11
)
[2] => Array
(
[companyperson_lastname] => Kallio
)
[3] => Array
(
[rc_lot_area_m2] => 2412.7
)
[56] => Array
(
[floors] => 3
)
[57] => Array
(
[total_area_m2] => 97.0
)
[58] => Array
(
[igglo_silentsale_realty_flag] => false
)
[59] => Array
(
[possession_partition_flag] => false
)
[60] => Array
(
[charges_parkingspace] => 10
)
[61] => Array
(
[0] => Array
(
[image_realtyimagetype_id] => yleiskuva
)
[1] => Array
(
[image_itemimagetype_name] => kivirealty-original
)
[2] => Array
(
[image_desc] => makuuhuone
)
)
)
And this is a live example of the translations array
Array
(
[0] => Array
(
[addr_region_area_id] => Maakunta
[group] => Kohde
)
[1] => Array
(
[addr_town_area] => Kunta
[group] => Kohde
)
[2] => Array
(
[arable_no_flag] => Ei peltoa
[group] => Kohde
)
[3] => Array
(
[arableland] => Pellon kuvaus
[group] => Kohde
)
)
I can build the translations array in another way. I did this like this, because in the second step I have to check, which group the keys belong to...
Try this :
$properties = array();
$translations = array();
$properties[] = array("Floor"=>"5qm");
$properties[] = array("Height"=>"10m");
$translations[] = array("Floor"=>"Boden");
$translations[] = array("Height"=>"Höhe");
$temp = call_user_func_array('array_merge_recursive', $translations);
$result = array();
foreach($properties as $key=>$val){
foreach($val as $k=>$v){
$result[$key][$temp[$k]] = $v;
}
}
echo "<pre>";
print_r($result);
output:
Array
(
[0] => Array
(
[Boden] => 5qm
)
[1] => Array
(
[Höhe] => 10m
)
)
Please note : I changed the array to $properties[] = array("Floor"=>"5qm");, Removed a level of array, I guess this is how you need to structure your array.
According to the structure of $properties and $translations, you somehow know how these are connected. It's a bit vague how the indices of the array match eachother, meaning the values in $properties at index 0 is the equivalent for the translation in $translations at index 0.
I'm just wondering why the $translations array need to have the same structure (in nesting) as the $properties array. To my opinion the word Height can only mean Höhe in German. Representing it as an array would suggest there are multiple translations possible.
So if you could narrow down the $translations array to an one dimensional array as in:
$translation = array(
"Height"=>"Höhe",
"Floor"=>"Boden"
);
A possible loop would be
$result = array();
foreach($properties as $i => $array2) {
foreach($array2 as $i2 => $array3) {
foreach($array3 as $key => $value) {
$translatedKey = array_key_exists($key, $translations) ?
$translations[$key]:
$key;
$result[$i][$i2][$translatedKey] = $value;
}
}
}
(I see every body posting 2 loops, it's an array,array,array structure, not array,array ..)
If you cannot narrow down the translation array to a one dimensional array, then I'm just wondering if each index in the $properties array matches the same index in the $translations array, if so it's the same trick by adding the indices (location):
$translatedKey = $translations[$i][$i2][$key];
I've used array_key_exists because I'm not sure a translation key is always present. You have to create the logic for each case scenario yourself on what to check or not.
This is a fully recursive way to do it.
/* input */
$properties[] = array(array("Floor"=>"5qm", array("Test"=>"123")));
$properties[] = array(array("Height"=>"10m"));
$translations[] = array(array("Floor"=>"Boden", array("Test"=>"Foo")));
$translations[] = array(array("Height"=>"Höhe"));
function array_flip_recursive($arr) {
foreach ($arr as $key => $val) {
if (is_array($val)) {
$arr[$key] = array_flip_recursive($val);
}
else {
$arr = #array_flip($arr);
}
}
return $arr;
}
function array_merge_it($arr) {
foreach ($arr as $key => $val) {
if (is_array($val)) {
$arr[$key] = array_merge_it($val);
} else {
if(isset($arr[$key]) && !empty($arr[$key])) {
#$arr[$key] = $arr[$val];
}
}
}
return $arr;
}
function array_delete_empty($arr) {
foreach ($arr as $key => $val) {
if (is_array($val)) {
$arr[$key] = array_delete_empty($val);
}
else {
if(empty($arr[$key])) {
unset($arr[$key]);
}
}
}
return $arr;
}
$arr = array_replace_recursive($properties, $translations);
$arr = array_flip_recursive($arr);
$arr = array_replace_recursive($arr, $properties);
$arr = array_merge_it($arr);
$arr = array_delete_empty($arr);
print_r($arr);
http://sandbox.onlinephpfunctions.com/code/d2f92605b609b9739964ece9a4d8f389be4a7b81
You have to do the for loop in this way. If i understood you right (i.e) in associative array first key is same (some index).
foreach($properties as $key => $values) {
foreach($values as $key1 => $value1) {
$propertyResult[] = array($translations[$key][$key1][$value1] => $properties[$key][$key1][$value1]);
}
}
print_r($propertyResult);

count of duplicate elements in an array in php

Hi,
How can we find the count of duplicate elements in a multidimensional array ?
I have an array like this
Array
(
[0] => Array
(
[lid] => 192
[lname] => sdsss
)
[1] => Array
(
[lid] => 202
[lname] => testing
)
[2] => Array
(
[lid] => 192
[lname] => sdsss
)
[3] => Array
(
[lid] => 202
[lname] => testing
)
)
How to find the count of each elements ?
i.e, count of entries with id 192,202 etc
You can adopt this trick; map each item of the array (which is an array itself) to its respective ['lid'] member and then use array_count_value() to do the counting for you.
array_count_values(array_map(function($item) {
return $item['lid'];
}, $arr);
Plus, it's a one-liner, thus adding to elite hacker status.
Update
Since 5.5 you can shorten it to:
array_count_values(array_column($arr, 'lid'));
foreach ($array as $value)
{
$numbers[$value[lid]]++;
}
foreach ($numbers as $key => $value)
{
echo 'numbers of '.$key.' equal '.$value.'<br/>';
}
Following code will count duplicate element of an array.Please review it and try this code
$arrayChars=array("green","red","yellow","green","red","yellow","green");
$arrLength=count($arrayChars);
$elementCount=array();
for($i=0;$i<$arrLength-1;$i++)
{
$key=$arrayChars[$i];
if($elementCount[$key]>=1)
{
$elementCount[$key]++;
} else {
$elementCount[$key]=1;
}
}
echo "<pre>";
print_r($elementCount);
OUTPUT:
Array
(
[green] => 3
[red] => 2
[yellow] => 2
)
You can also view similar questions with array handling on following link
http://solvemyquest.com/count-duplicant-element-array-php-without-using-built-function/
The following code will get the counts for all of them - anything > 1 at the end will be repeated.
<?php
$lidCount = array();
$lnameCount = array();
foreach ($yourArray as $arr) {
if (isset($lidCount[$arr['lid']])) {
$lidCount[$arr['lid']]++;
} else {
$lidCount[$arr['lid']] = 1;
}
if (isset($lnameCount [$arr['lname']])) {
$lnameCount [$arr['lname']]++;
} else {
$lnameCount [$arr['lname']] = 1;
}
}
$array = array('192', '202', '192', '202');
print_r(array_count_values($array));
$orders = array(
array(
'lid' => '',
'lname' => '',
))....
$foundIds = array();
foreach ( $orders as $index => $order )
{
if ( isset( $foundIds[$order['lid']] ) )
{
$orders[$index]['is_dupe'] = true;
$orders[$foundIds[$order['lid']]]['is_dupe'] = true;
} else {
$orders[$index]['is_dupe'] = false;
}
$foundIds[$order['lid']] = $index;
}
Try this code :
$array_count = array();
foreach ($array as $arr) :
if (in_array($arr, $array_count)) {
foreach ($array_count as $key => $count) :
if ($key == $arr) {
$array_count[$key]++;
break;
}
endforeach;
} else {
$array_count[$arr] = 1;
}
endforeach;
Check with in_array() function.

Categories