I want to implode this array to make a string with all keys = 'Palabra'. How can this be done? (the output should be: 'juana es')
Array
(
[0] => Array
(
[Palabra] => juana
)
[1] => Array
(
[Palabra] => es
[0] => Array
(
[Raiz] => ser
[Tipo] => verbo
[Tipo2] => verbo1
)
)
)
function foo( $needly, $array ) {
$results = array();
foreach ( $array as $key => $value ) {
if ( is_array( $value ) ) {
$results = array_merge($results, foo( $needly, $value ));
} else if ( $key == $needly ) {
$results[] = $value;
}
}
return $results;
}
echo implode( " ", foo( "Palabra", $your_array ) );
I ended using the foreach for lack of a better solution:
foreach ($array as $key => $palabra) {
$newArray[] = $array[$key]["Palabra"];
}
$string = implode(' ', $newArray);
I think the simplest solution is with array_walk_recursive.
<?php
$arr = array(
array(
'Palabra' => 'juana',
),
array(
'Palabra' => 'es',
array(
'Raiz' => 'ser',
'Tipo' => 'verbo',
'Tipo2' => 'verbo1',
),
),
);
$str = array();
array_walk_recursive($arr, function($value, $key) use(&$str) {
if ($key == 'Palabra') {
$str[] = $value;
}
});
$str = implode(' ', $str);
echo "$str\n";
The function passed in is called for each key-value pair in the array and any subarrays. Here we append any values with a matching key to an array and then implode the array to get a string.
Related
I'm trying to get an xml file from an associative array having array keys encapsuled into '<' and '>'
I've tried to use a recursive function but it works correctly only on the first level:
Please remember my final goal is to create an xml, so any appropriate suggest is welcome
this is what I've done so far:
$arr =
array('<Lev0_0>' => 0,
'<Lev0_1>' => 1,
'<Lev0_2>' => array (
'<Lev1_0>' => 2,
'<Lev1_1>' => 3
)
);
print_r(RepairKeysMultidimensional($arr));
function RepairKeysMultidimensional(array $array){
$Keys = array();
foreach($array as $Key => $Value){
$NewKey = str_replace(array('<','>'),'',$Key);
$array[$NewKey] = $Value;
unset($array[$Key]);
if(is_array($Value)){
RepairKeysMultidimensional($Value);
}
}
return $array;
}
the output is:
Array (
[Lev0_0] => 0
[Lev0_1] => 1
[Lev0_2] => Array (
[] => 2
[] => 3
)
)
If that's the structure and you never expect < or > as part of the values, you don't need to loop over it just json_encode it, strip out the chars and the json_decode it back into an array.
<?php
$arr = array(
'<Lev0_0>' => 0,
'<Lev0_1>' => 1,
'<Lev0_2>' => array (
'<Lev1_0>' => 2,
'<Lev1_1>' => 3
)
);
$arr = json_decode(str_replace(array('<','>'), '', json_encode($arr)), true);
print_r($arr);
https://3v4l.org/2d7Hq
Result:
Array
(
[Lev0_0] => 0
[Lev0_1] => 1
[Lev0_2] => Array
(
[Lev1_0] => 2
[Lev1_1] => 3
)
)
Try to add affectation in your if statement:
function RepairKeysMultidimensional(array $array){
$Keys = array();
foreach($array as $Key => $Value){
$NewKey = str_replace(array('<','>'),'',$Key);
$array[$NewKey] = $Value;
unset($array[$Key]);
if (is_array($Value)) {
$array[$NewKey] = RepairKeysMultidimensional($Value);
}
}
return $array;
}
you are not affecting the result of the second call to the outer array!
Try this :
<?php
$arr =
array('<Lev0_0>' => 0,
'<Lev0_1>' => 1,
'<Lev0_2>' => array (
'<Lev1_0>' => 2,
'<Lev1_1>' => 3
)
);
echo str_replace(array('<','>'),'','<Lev0>');
echo '<br/><br/>';
print_r(RepairKeysMultidimensional($arr));
function RepairKeysMultidimensional(array $array){
$Keys = array();
foreach($array as $Key => $Value){
$NewKey = str_replace(array('<','>'),'',$Key);
unset($array[$Key]);
if(is_array($Value)){
$array[$NewKey] = RepairKeysMultidimensional($Value);
}else{
$array[$NewKey] = $Value;
}
}
return $array;
}
The output of this is :
Array (
[Lev0_0] => 0
[Lev0_1] => 1
[Lev0_2] => Array (
[Lev1_0] => 2
[Lev1_1] => 3 ) )
I have two arrays:
('admin','admin2', 'admin3' can be too many, and names can also differ other than 'admin')
$old = array(
array('admin'=>array('a'=>'aaa','b'=>'bbb')),
array('admin2'=>array('c'=>'ccc','d'=>'ddd'))
);
$new = array(
array('admin2'=>array('e'=>'eee','f'=>'fff')),
array('admin3'=>array('g'=>'ggg','h'=>'hhh'))
);
I want to have this array from both above arrays:
(new array with all different keys in both PLUS similar keys from new array)
$output = array(
array('admin'=>array('a'=>'aaa','b'=>'bbb')),
array('admin2'=>array('e'=>'eee','f'=>'fff')),
array('admin3'=>array('g'=>'ggg','h'=>'hhh'))
);
// Remove one level of array to make arrays as ['admin'=>array, 'admin2'=>array]
$old1 = call_user_func_array('array_merge', $old);
$new1 = call_user_func_array('array_merge', $new);
// Make replacement
$ready = array_replace($old1, $new1);
// Return level making every item as array
$result = array();
foreach($ready as $k=>&$v)
$result[] = array($k=>$v);
print_r($result);
demolink
This code will solve your problem :
<?php
$array1 = array(
array('admin'=>array('a'=>'aaa','b'=>'bbb')),
array('admin2'=>array('c'=>'ccc','d'=>'ddd'))
);
$array2 = array(
array('admin2'=>array('e'=>'eee','f'=>'fff')),
array('admin3'=>array('g'=>'ggg','h'=>'hhh'))
);
$output = $array1; ///merge array1 into output array
foreach($array2 as $key => $val)
{
$is_present_key = false;
$first_key = key($val);
foreach($output as $k => $v)
{
if(array_key_exists($first_key,$output[$k])) ////check if key exit in $output array
{
$output[$k] = $val; ///push new value if key exists in $output
$is_present_key = true;
}
}
if($is_present_key == false)///skip for duplicate of new values if key exists in $output
{
$output[] = $val;
}
}
echo "<pre>"; print_r($output);
?>
This will give you :
Array
(
[0] => Array
(
[admin] => Array
(
[a] => aaa
[b] => bbb
)
)
[1] => Array
(
[admin2] => Array
(
[e] => eee
[f] => fff
)
)
[2] => Array
(
[admin3] => Array
(
[g] => ggg
[h] => hhh
)
)
)
LIVE EXAMPLE
$old = array(
array('admin'=>array('a'=>'aaa','b'=>'bbb')),
array('admin2'=>array('c'=>'ccc','d'=>'ddd'))
);
$new = array(
array('admin2'=>array('e'=>'eee','f'=>'fff')),
array('admin3'=>array('g'=>'ggg','h'=>'hhh'))
);
$arr=array_merge($new,$old);
$new_arr=array();
foreach($arr as $key=>$val){
foreach($val as $k=>$v){
if(array_key_exists($k, $new_arr)){
continue;
}else{
$new_arr[$k]=$v;
}
}
}
echo "<pre>";print_r($new_arr); echo "</pre>";
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>";
}
}
I have an array with n elements in it, with each element containing n child elements, each containing...
Array
(
[tea] => Array
(
[drink] => Array
(
[food] =>
)
)
[biscuits] => Array
(
[snack] => Array
(
[food] =>
)
)
...
)
What I want to do is have the inner most element on the outside, and the outer most elements on the inside:
Array
(
[food] => Array
(
[drink] => Array
(
[tea] =>
)
[snack] => Array
)
[biscuits] =>
(
)
...
)
And the solution needs to be able to deal with n children arrays. I am aware of How do I invert a multidimensional array in PHP but the solutions there did not solve this problem.
I'm pretty sure this could be condensed further, but it does the job:
function flatten(array $array) {
$key = array(key($array));
$val = current($array);
if (is_array($val)) {
$key = array_merge(flatten($val), $key);
}
return $key;
}
function build(array $path, array $result) {
$key = array_shift($path);
if (!isset($result[$key])) {
$result[$key] = $path ? array() : null;
}
if ($path) {
$result[$key] = build($path, $result[$key]);
}
return $result;
}
$result = array();
foreach ($array as $key => $value) {
$result = build(flatten(array($key => $value)), $result);
}
Demo: http://codepad.org/rnZPdWGG
I have a few associative arrays that I need to merge together based on there key.
so:
array1:
[person1] => tony
[person2] => sandra
array2:
[person1] => london
[person2] => paris
needs to be :
array 3
[person1] => tony , london
[person2] => sandra , paris
The issue I'm having though is that the key could be any value , so it could be 'person1' or it could be 'hairyOtter' and the array is of varaible size.
Assuming, that every is not multi-dimensional
$merged = array_merge_recursive($array1, $array2);
foreach ($merged as &$entry) {
if (is_array($entry)) {
$entry = implode(', ', $entry);
}
}
The idea is, that array_merge_recursive() creates a new array, if it find two values with the same key. Everything else stays untouched.
I'm sure there are more efficient ways to accomplish this, but for now, this works:
<?php
function combine( $keys, $first, $second ) {
$args = func_get_args( );
$keys = array_shift( $args );
$arrays = $args;
$result = array( );
foreach( $keys as $key ) {
foreach( $arrays as $array ) {
if( isset( $array[$key] ) ) {
$result[$key][] = $array[$key];
}
}
}
return $result;
}
$first = array(
'person1' => 'tony',
'person2' => 'sandra'
);
$second = array(
'person1' => 'london',
'person2' => 'paris'
);
/**
* To make sure you get *every* key out of both arrays.
*/
$keys = array_unique( array_merge( array_keys( $first ), array_keys( $second ) ) );
$combined = combine( $keys, $first, $second );
var_dump( $combined );
Two loops should do it. Iterate over each of array1 and array2, initialising array3's keys as you go to an array, and pushing into that array. Here's the first loop
$array3 = array();
foreach (array_keys($array1) as $key) {
if(!array_key_exists($key, $array3)) {
$array3[$key] = array();
}
array_push($array3[$key], $array1[$key]);
}
$array1 = array('a' => 1, 'b' => 2);
$array2 = array('a' => 3, 'b' => 4, 'c' => 5);
foreach ($array1 as $k => $v) {
$tArray[$k][] = $v;
}
foreach ($array2 as $k => $v) {
$tArray[$k][] = $v;
}
foreach ($tArray as $k => $v) {
$tArray[$k] = implode(',',$tArray[$k]);
}
I would create a multi-dimensional array instead, unless there is a specific reason you can't use one. This way, you would have an array that looks like:
Array
(
[Person1] => Array
(
[Name] => Tony
[City] => London
)
[Person2] => Array
(
[Name] => Sandra
[City] => Paris
)
)