I'm having an array key-value pair. I need to create new array from this key and value pair. for eg
I tried with foreach loop
foreach($array as $key => $val){
// here i m getting key and value i want to combine key and value in single array
}
Array
(
'146' => Array
(
'sam' => Array (
'dex',
'max'
)
)
'143' => Array
(
'tim' => Array (
'thai',
'josh'
)
)
)
and the expected output is push key as first element
$out = [
[ 'sam', 'dex', 'max'],
[ 'tim','thai', 'josh']
];
You can use array-merge as:
foreach($array as $key => $val)
$out[] = array_merge([$key], $val);
Notice that in your example you also have another level of keys ("146", "143") -> you need to remove it before using this code.
Edited:
foreach($arr as $val) {
$key = key($val);
$out[] = array_merge([$key], $val[$key]);
}
Live example: 3v4l
What about this?
$output = [];
foreach($array as $key => $val) {
$data = $val;
array_unshift($data, $key);
$output[] = $data;
}
So, we need to flatten the array for each key in your array.
We make a function which recursively calls the further deep arrays and we collect all these results in a new array which is passed as a second parameter.
Code:
<?php
$arr = Array(
'146' => Array
(
'sam' => Array (
'dex',
'max'
)
),
'143' => Array
(
'tim' => Array (
'thai',
'josh'
)
)
);
$result = [];
foreach($arr as $key => $value){
$flat_data = [];
flattenArray($value,$flat_data);
$result[] = $flat_data;
}
function flattenArray($data,&$flat_data){
foreach ($data as $key => $value) {
if(is_array($value)){
$flat_data[] = $key;
flattenArray($value,$flat_data);
}else{
$flat_data[] = $value;
}
}
}
print_r($result);
Demo: https://3v4l.org/bX9R3
Since, we are passing a new array to collect the results as second parameter, this would perform better than returning an array of results on each function call and then doing an array merge(which would have made a bit inefficient).
This would work independent of the depth of levels.
Related
I want to consolidate an associative array of indexed arrays by merging rows which have an associative key that is in another row's values.
Consider this sample input:
$array = [
44259 => [50007, 50009, 46372],
50007 => [50008],
50009 => [50010],
66666 => ['no', 'other', 'links'],
46372 => [46418, 46419, 46421],
46421 => [146880]
];
Because the values in the 44259-keyed row (50007, 50009, and 46372) exist as keys in the original array, all of the values from those values should be pushed into the 44259-keyed row.
Continuing the same logic, after the 46372-keyed rows have been added to 44259-keyed row, now the 46421-keyed row values should be pushed into the growing 44259-keyed row.
Desired result:
$array = [
44259 => [
50007, // original
50009, // original
46372, // original
50008, // from 50007
50010, // from 50009
50018, // from 46372
46419, // from 46372
46421, // from 46372
146880, // from 46372 -> 46421
66666 => [
'no',
'other',
'links'
]
];
You see, this is somewhat of a recursive task.
I tried this already:
foreach ($array as $cid => $pid) {
foreach ($pid as $pip) {
if (isset($array[$pipp])) {
foreach ($array[$pipp] as $pip) {
$array[$cid][] = $pip;
unset($array[$pipp]);
}
}
}
}
But it's not properly collecting the 46372 row's data for the 44259 row.
You could get the first key using array_keys() and reset(). Then you could add values of all array to this key:
$array = [];
$array[44259] = [50007, 50009, 46372];
$array[50007] = [50008];
$array[50009] = [50010];
$array[46372] = [46418, 46419, 46421];
$array[46421] = [146880];
$out = [];
$keys = array_keys($array);
$first_key = reset($keys); // $first_key = 44259
foreach ($array as $k => $items) {
foreach ($items as $val) {
$out[$first_key][] = $val;
}
}
print_r($out);
Outputs:
Array
(
[44259] => Array
(
[0] => 50007
[1] => 50009
[2] => 46372
[3] => 50008
[4] => 50010
[5] => 46418
[6] => 46419
[7] => 46421
[8] => 146880
)
)
You coukd try just merging
$result =array_merge($array[44259],$array[50007] ,$array[50009] ,
$array[46372], $array[46421] );
$res = array();
$res[44259] = array();
foreach($array as $pid)
$res[44259] = array_merge($res[44259], $pid);
print_r($res);
?>
Ouput
Array
(
[44259] => Array
(
[0] => 50007
[1] => 50009
[2] => 46372
[3] => 50008
[4] => 50010
[5] => 46418
[6] => 46419
[7] => 46421
[8] => 146880
)
)
This is probably one way of doing it. Create another array and push all the variables in the new array.
$result=[];
foreach ($array as $v1) {
foreach ($v1 as $v2) {
array_push($result,$v2);
}
}
Have you tried array_merge?
$mergedArray = [];
foreach ($array as $subArray) {
$mergedArray = array_merge ($mergedArray, $subArray);
}
If that doesn't work, then you could probably use array_map to run a function on each sub array element to check if it is in the merged array before adding it.
$mergedArray = [];
foreach ($array as $subArray) {
array_map(function($elm) {
if (!in_array($elm, $mergedArray)) {
$mergedArray[] = $elm;
}, $subArray);
}
You were very close, but you need to allow your script to restart the full array loop after consolidating data.
I recommend a do{}while() loop so that the inner processing can be repeated until there are no qualifying/moveable rows.
A nested loop is then used to search for first level keys that match any of the row values. Make the rows modifiable by reference with & -- this will ensure that the data manipulations are upon the original array and not merely a copy of the original array.
When there is a matching key, push the entire found row into the parent row, then remove the now-empty row from the original array, then toggle the flag indicating that another loop is required, then break
Code: (Demo)
do {
$changes = false;
foreach ($array as $k => &$row) {
foreach ($row as $v) {
if (isset($array[$v])) {
array_push($array[$k], ...$array[$v]);
unset($array[$v]);
$changes = true;
}
}
}
} while($changes);
var_export($array);
Having issues converting an array like this into an associative array
$array =
Array
(
[0] => 154654654455|WS01
[1] => 456541232132|WS02
)
Into an associative array.
I can do a foreach loop and explode the values
$values2 = array();
foreach ($array as $key => $value) {
$values2[] = explode("|",$value);
}
But then I get something like this
Array
(
[0] => Array
(
[0] => 154654654455
[1] => WS01
)
[1] => Array
(
[0] => 456541232132
[1] => WS02
)
)
What's the best way to convert something like this into an associative array like such
Array
(
[154654654455] => WS01
[456541232132] => WS02
)
$values2 = array();
foreach ($array as $key => $value) {
$expl = explode("|",$value);
$values2[$expl[0]] = $expl[1];
}
Probably not the most elegant way, but modifying your approach it would be:
$values2 = array();
foreach ($array as $key => $value) {
$t = explode("|",$value);
$values2[$t[0]] = $t[1];
}
change your foreach loop to this
foreach ($array as $key => $value) {
$temp = explode("|",$value);
$values2[$temp[0]] = $temp[1];
}
All you need to do is to set the the first item of the explode as key and the second as value:
$array = [
'154654654455|WS01',
'456541232132|WS02',
];
$values2 = [];
foreach ($array as $key => $value) {
$data = explode('|', $value);
$values2[$data[0]] = $data[1];
}
Demo: https://3v4l.org/cEJE5
Not the best answer, but for completeness; after your loop you can extract the 1 column as values and index on the 0 column:
$values2 = array_column($values2, 1, 0);
I am going to put the exact same answer here as everyone else,but I will omit the unused $key variable...
$val2 = array();
foreach ($array as $v) {
$tmp = explode("|",$v);
$val2[$tmp[0]] = $tmp[1];
}
For the building of a url query I need to combine one value(key) of an array to all the values(value) of another array. Each combined key => value needs to be added to an array.
The problem here is that I can combine the values of the two arrays in two foreach statements, but it creates for every instance a new array.
Update
Having duplicates is impossible so mine initial output is correct.
$array1 array(
[0] => music
[1] => product
)
$array2 array(
[0] => '));waitfor delay '0:0:TIME'--1
[1] => '[TAB]or[TAB]sleep(TIME)='
)
public static function create_combined_array($array1, $array2)
{
$newArray = array();
foreach ($array1 as $key){
//key = [music]
foreach ($array2 as $value) {
//one of the values is = '));waitfor delay '0:0:__TIME__'--1
array_push($newArray, [$key => $value]);
}
}
return $newArray;
}
Implementation
$query_array = Utils::create_combined_array($params, $payload_lines);
print_r($query_array);
$query = http_build_query($query_array);
$this->url = $baseUrl . '?' . $query;
Build query output
protocol://localhost:8000?music='));waitfor delay '0:0:TIME'--1
Sample output
[54] => Array
(
[music] => ));waitfor delay '0:0:__TIME__'--[LF]1
)
[55] => Array
(
[music] => '));waitfor delay '0:0:__TIME__'--1
)
[56] => Array
(
[music] => '));waitfor delay '0:0:__TIME__'--[LF]1
)
[57] => Array
(
[music] => "));waitfor delay '0:0:__TIME__'--1
)
What I wanted to achieve is impossible in PHP.
Example duplicates
Array(
[music] => "));waitfor delay '0:0:__TIME__'--1
[music] => '/**/or/**/benchmark(10000000,MD5(1))#1
)
Use code below:
public static function create_combined_array($array1, $array2)
{
$newArray = array();
foreach ($array1 as $key){
foreach ($array2 as $i => $value) {
$newArray[$i][$key] = $value;
}
}
return $newArray;
}
The key line is $newArray[$i][$key] = $value;. It appends an array to the $newArray at $i index which is the index of your second array $array2.
I have an array that looks something like this:
Array (
[0] => Array ( [country_percentage] => 5 %North America )
[1] => Array ( [country_percentage] => 0 %Latin America )
)
I want only numeric values from above array. I want my final array like this
Array (
[0] => Array ( [country_percentage] => 5)
[1] => Array ( [country_percentage] => 0)
)
How I achieve this using PHP?? Thanks in advance...
When the number is in first position you can int cast it like so:
$newArray = [];
foreach($array => $value) {
$newArray[] = (int)$value;
}
I guess you can loop the 2 dimensional array and use a preg_replace, i.e.:
for($i=0; $i < count($arrays); $i++){
$arrays[$i]['country_percentage'] = preg_replace( '/[^\d]/', '', $arrays[$i]['country_percentage'] );
}
Ideone Demo
Update Based on your comment:
for($i=0; $i < count($arrays); $i++){
if( preg_match( '/North America/', $arrays[$i]['country_percentage'] )){
echo preg_replace( '/[^\d]/', '', $arrays[$i]['country_percentage'] );
}
}
Try this:
$arr = array(array('country_percentage' => '5 %North America'),array("country_percentage"=>"0 %Latin America"));
$result = array();
foreach($arr as $array) {
$int = filter_var($array['country_percentage'], FILTER_SANITIZE_NUMBER_INT);
$result[] = array('country_percentage' => $int);
}
Try this one:-
$arr =[['country_percentage' => '5 %North America'],
['country_percentage' => '0 %Latin America']];
$res = [];
foreach ($arr as $key => $val) {
$res[]['country_percentage'] = (int)$val['country_percentage'];
}
echo '<pre>'; print_r($res);
output:-
Array
(
[0] => Array
(
[country_percentage] => 5
)
[1] => Array
(
[country_percentage] => 0
)
)
You can use array_walk_recursive to do away with the loop,
passing the first parameter of the callback as a reference to modify the initial array value.
Then just apply either filter_var or intval as already mentioned the other answers.
$array = [
["country_percentage" => "5 %North America"],
["country_percentage" => "0 %Latin America"]
];
array_walk_recursive($array, function(&$value,$key){
$value = filter_var($value,FILTER_SANITIZE_NUMBER_INT);
// or
$value = intval($value);
});
print_r($array);
Will output
Array
(
[0] => Array
(
[country_percentage] => 5
)
[1] => Array
(
[country_percentage] => 0
)
)
You could get all nemeric values by looping through the array. However I don't think this is the most efficient and good looking answer, I'll post it anyways.
// Array to hold just the numbers
$newArray = array();
// Loop through array
foreach ($array as $key => $value) {
// Check if the value is numeric
if (is_numeric($value)) {
$newArray[$key] = $value;
}
}
I missunderstood your question.
$newArray = array();
foreach ($array as $key => $value) {
foreach ($value as $subkey => $subvalue) {
$subvalue = trim(current(explode('%', $subvalue)));
$newArray[$key] = array($subkey => $subvalue);
}
}
If you want all but numeric values :
$array[] = array("country_percentage"=>"5 %North America");
$array[] = array("country_percentage"=>"3 %Latin America");
$newArray = [];
foreach ($array as $arr){
foreach($arr as $key1=>$arr1) {
$newArray[][$key1] = intval($arr1);
}
}
echo "<pre>";
print_R($newArray);
This is kind of a ghetto method to doing it cause I love using not as many pre made functions as possible. But this should work for you :D
$array = array('jack', 2, 5, 'gday!');
$new = array();
foreach ($array as $item) {
// IF Is numeric (each item from the array) will insert into new array called $new.
if (is_numeric($item)) { array_push($new, $item); }
}
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);