$arr1 = array('a' => '1', 'b' => 'blah', 'c' => 'whatever...',
'aa' => '2', 'bb' => 'lbha', 'cc' => 'everwhat...', 'dd' => 'bingo',
'aaa' => '3', 'bbb' => 'halb', 'ccc' => 'revetahw...');
In the array I have three different index lengths a,b and c are all 1 in length. aa,bb,cc and dd are all 2 in length. And aaa,bbb and ccc are all 3 in length.
What I'm trying to do is find the index (group by length) with the most elements and the greatest length.
so I would use aa,bb,cc,dd as they have 4 elements, this would return the index length of 2.
I want to know how I can get the 2?
Here is what I'm trying but it's not working
foreach($arr1 as $key => $data) {
$index_length_arr[strlen($key)] = $index_length_arr[$key] + 1;
}
Results:
Array
(
[1] => 1
[2] => 1
[3] => 1
)
Expected Output:
Array
(
[1] => 3
[2] => 4
[3] => 3
)
Then I could see that index (with the length of 2) had the most elements:
'aa' => '2', 'bb' => 'lbha', 'cc' => 'everwhat...', 'dd' => 'bingo',
$array = array_count_values(array_map('strlen',array_keys($arr1)));
Should give ya what ya want.
Edit:
Your original code was fine except you have to change the = .... to $index_length_arr[strlen($key)]
You were using two different keys.
I'd recommend creating your own (or using a library that already does it). It'd be something like this (did not test it):
function groupBy($array, $function)
{
$dictionary = [];
if ($array) {
foreach ($array as $item) {
$dictionary[$function($item)][] = $item;
}
}
return $dictionary;
}
Using it like this:
$usersByAge = groupBy($users, function ($age) { return $user->age; } );
I would highly recommend using lstrojny's functional-php https://github.com/lstrojny/functional-php which includes a group() function along with a host of other useful functional programming concepts.
$arr1 = array('a' => '1', 'b' => 'blah', 'c' => 'whatever...',
'aa' => '2', 'bb' => 'lbha', 'cc' => 'everwhat...', 'dd' => 'bingo',
'aaa' => '3', 'bbb' => 'halb', 'ccc' => 'revetahw...');
$tmpArray = array();
foreach ($arr1 AS $key => $val) {
if (empty($tmpArray)) {
$tmpArray[strlen($key)] = 0;
}
$tmpArray[strlen($key)]++;
}
print_r($tmpArray);
Gets you your expected result.
Related
This question already has answers here:
How to Flatten a Multidimensional Array?
(31 answers)
Closed 5 months ago.
I have following array keys values:
$arrData = array
(
array(
'a' => 'test',
'c' => 1,
'd' => 2,
'e' => 'B'
),
array(
'c' => 1,
'd' => 2,
'e' => 'B'
),
array(
'b' => 'test2',
'c' => 1,
'd' => 2,
'e' => 'B'
)
);
So here I need to merged array into single with combining missing keys with single value array.
Can someone please help to get following output in single array?
$arrData = array
(
array(
'a' => 'test',
'b' => 'test2',
'c' => 1,
'd' => 2,
'e' => 'B'
)
);
Thanking in advance!
Just merge them and then sort on the key:
$arrData = array_merge(...$arrData);
ksort($arrData);
Instead of ... you can use:
$arrData = call_user_func_array('array_merge', $arrData);
If you really want the result to be multi-dimensional, then:
$arrData = [$arraData];
//or
$arrData = array($arrData);
You can use array_reduce (or a simple foreach loop) to merge each of the subsequent array values with the first one:
$out = array_reduce($arrData, function ($c, $v) { return array_merge($c, $v); }, array());
print_r($out);
$out = array();
foreach ($arrData as $arr) {
$out = array_merge($out, $arr);
}
print_r($out);
Output (for both examples):
Array (
[a] => test
[c] => 1
[d] => 2
[e] => B
[b] => test2
)
If you want to keep the keys in alphabetical order, you can use ksort:
ksort($out);
print_r($out);
Array (
[a] => test
[b] => test2
[c] => 1
[d] => 2
[e] => B
)
Demo on 3v4l.org
Using array_walk and ksort
$res=[];
array_walk($arrData, function($v,$k) use(&$res){
$res = array_merge($res,$v);
});
ksort($res);
OR
You can use foreach and array_column
$keys = ['a','b','c','d','e'];
$res=[];
foreach($keys as $val){
$res[$val] = array_column($arrData, $val)[0];
}
print_r($res);
Live Demo
<?php
$arrData = array
(
array(
'a' => 'test',
'c' => 1,
'd' => 2,
'e' => 'B'
),
array(
'c' => 1,
'd' => 2,
'e' => 'B'
),
array(
'b' => 'test2',
'c' => 1,
'd' => 2,
'e' => 'B'
)
);
$result_array = array();
foreach($arrData as $ad){
foreach($ad as $key=>$value){
if(!array_key_exists($key,$result_array)){
$result_array[$key] = $value;
}
}
}
print_r($result_array);
?>
This question already has answers here:
Add a prefix to each item of a PHP array
(7 answers)
PHP - Replace data within multidimensional array, specific key
(2 answers)
Closed 6 years ago.
I have array like
$arr = array(1 => array('name' => 'abc', 'age' =>25), 2 => array('name' => 'xyz', 'age' =>28))
and i want to add prefix Mr. to the name value. So array will become
$arr = array (1 => array('name' => 'Mr. abc', 'age' =>25), 2 => array('name' => 'Mr. xyz', 'age' =>28))
In php can i do this?
You can manipulate the "name" index value according to your requirement like :
$arr = array (1 => array('name' => 'abc', 'age' =>25), 2 => array('name' => 'xyz', 'age' =>28));
foreach ($arr as $key => $val) {
$arr[$key]['name'] = 'Mr. '.$val['name'];
}
click on this link to see result
Assuming your array name is $array...
foreach($array as $id=>$el){
$array[$id]['name']='Mr '.$el['name'];
}
Please try the below code. It may help you.
$array = array(1 => array('name' => 'abc', 'age' =>25), 2 => array('name' => 'xyz', 'age' =>28));
foreach($array as &$element)
{
$element['name']= 'Mr. '.$element['name'];
}
print_r($array);
Use array_map - Applies the callback to the elements of the given arrays.
Example-
<?php
function funct($ar) {
$ar['name'] = "Mr. ".$ar['name'];
return $ar;
}
$array = array(1 => array('name' => 'abc', 'age' =>25), 2 => array('name' => 'xyz', 'age' =>28));
$array = array_map('funct', $array);
pr($array);
?>
try this is code
<?php
$array= Array (1 => array('name' => 'abc', 'age' =>25), 2 => array('name' => 'xyz', 'age' =>28));
foreach($array as &$value) {
$value['name'] = 'MR. '.$value['name'];
}
print_r($array);
?>
/* output
Array ( [1] => Array ( [name] => MR. abc [age] => 25 ) [2] => Array ( [name] => MR. xyz [age] => 28 ) )
*/
This question already has answers here:
Change array key without changing order
(8 answers)
Closed 7 years ago.
How i can do this:
$array = array('a' => 1, 'd' => 2, 'c' => 3); //associative array
// rename $array['d'] as $array['b']
$array = replace_key_function($array, 'd', 'b');
var_export($array); // array('a' => 1, 'b' => 2, 'c' => 3); same order!
I didn't see a function that does that.
There is a way to do this?
http://ideone.com/nCZnY
$array = array('a' => 1, 'd' => 2, 'c' => 3); //associative array
// rename $array['d'] as $array['b']
$array = replace_key_function($array, 'd', 'b');
var_export($array); // array('a' => 1, 'b' => 2, 'c' => 3); same order!
function replace_key_function($array, $key1, $key2)
{
$keys = array_keys($array);
$index = array_search($key1, $keys);
if ($index !== false) {
$keys[$index] = $key2;
$array = array_combine($keys, $array);
}
return $array;
}
There is a flaw in the logic of the accepted answer.
If you have an array like this:
[
'k1'=>'k1',
'k2'=>'k2',
'k3',
'k4'=>'k4'
]
and replace 'k4' with 'something' you will get an output like this:
[
'k1'=>'k1',
'k2'=>'k2',
'something' => 'k3',
'k4'=>'k4'
]
Here is a quick fix that solves the problem:
function replace_key_function($array, $key1, $key2)
{
$keys = array_keys($array);
//$index = array_search($key1, $keys);
$index = false;
$i = 0;
foreach($array as $k => $v){
if($key1 === $k){
$index = $i;
break;
}
$i++;
}
if ($index !== false) {
$keys[$index] = $key2;
$array = array_combine($keys, $array);
}
return $array;
}
EDIT:2014/12/03
The accepted answer does work if you set the third parameter (strict) of array_search to true.
Instead of using loops, you could always flatten to string with json_encode(), perform a string replacement, then json_decode() back to an array:
function replaceKey($array, $old, $new)
{
//flatten the array into a JSON string
$str = json_encode($array);
// do a simple string replace.
// variables are wrapped in quotes to ensure only exact match replacements
// colon after the closing quote will ensure only keys are targeted
$str = str_replace('"'.$old.'":','"'.$new.'":',$str);
// restore JSON string to array
return json_decode($str, TRUE);
}
Now this doesn't check for conflicts with pre-existing keys (easy enough to add a string comparison check), and it might not be the best solution for single replacements in massive arrays.. but the nice part about flattening the array into a string for replacement is that it effectively makes replacement recursive since matches at any depth are all replaced in one pass:
$arr = array(
array(
'name' => 'Steve'
,'city' => 'Los Angeles'
,'state' => 'CA'
,'country' => 'USA'
,'mother' => array(
'name' => 'Jessica'
,'city' => 'San Diego'
,'state' => 'CA'
,'country' => 'USA'
)
)
,array(
'name' => 'Sara'
,'city' => 'Seattle'
,'state' => 'WA'
,'country' => 'USA'
,'father' => array(
'name' => 'Eric'
,'city' => 'Atlanta'
,'state' => 'GA'
,'country' => 'USA'
,'mother' => array(
'name' => 'Sharon'
,'city' => 'Portland'
,'state' => 'OR'
,'country' => 'USA'
)
)
)
);
$replaced = replaceKey($arr,'city','town');
print_r($replaced);
outputs
Array
(
[0] => Array
(
[name] => Steve
[town] => Los Angeles
[state] => CA
[country] => USA
[mother] => Array
(
[name] => Jessica
[town] => San Diego
[state] => CA
[country] => USA
)
)
[1] => Array
(
[name] => Sara
[town] => Seattle
[state] => WA
[country] => USA
[father] => Array
(
[name] => Eric
[town] => Atlanta
[state] => GA
[country] => USA
[mother] => Array
(
[name] => Sharon
[town] => Portland
[state] => OR
[country] => USA
)
)
)
)
A generic and simple solution with PHP 5.3+ using array_walk:
$array = array('a' => 1, 'd' => 2, 'c' => 3); //associative array
$array = replace_keys($array, array('d' => 'b'));
var_export($array); // array('a' => 1, 'b' => 2, 'c' => 3); same order!
function replace_keys(array $source, array $keyMapping) {
$target = array();
array_walk($source,
function ($v, $k, $keyMapping) use (&$target) {
$mappedKey = isset($keyMapping[$k]) ? $keyMapping[$k] : $k;
$target[$mappedKey] = $v;
},
$keyMapping);
return $target;
}
a good answer has been posted, but here's my two pence:
$array = array('a'=>1, 'd'=>2, 'c'=>3);
// rename 'd' to 'b'
foreach($array as $k=>$v){
if($k == 'd') { $k='b'; }
$newarray[$k] = $v;
}
$array = $newarray;
in response to mike-purcell would this be a more accepted approach to my example above?
changeKey($array, 'd', 'b');
function changeKey($array, $oldKey, $newKey)
{
foreach($array as $k=>$v){
if($k == $oldKey) { $k = $newKey; }
$returnArray[$k] = $v;
}
return $returnArray;
}
I'm always looking to improve :)
I have an array inside an array and I'd like to simply print out the contents of it... the problem is what I'm trying doesn't work... ie
foreach($retval as $k=>$v){
if (is_array($v)){
foreach($v as $l=>$w){
echo $l . ' = ' . $w . '<br />';
}
} else {
echo $k . ' = ' . $v . '<br />';
}
Doing that however I end up with:
id = 2
name = Speakers
form_field = hidden
display_order = 0
groups = Array
So I'm not getting a foreach in that inside array.. what am I doing wrong? It seems actually that my code believes everything return is an array when I'm pretty sure that only 'groups' is an array.
the structure of the array looks like so:
array ( 0 => array ( 'id' => 2, 'name' => 'Speakers', 'form_field' => 'hidden', 'display_order' => '0', 'groups' => array ( 0 => array ( 'bit' => '1', 'name' => 'don', 'display_order' => '4', 'subscribers' => 8, ), 1 => array ( 'bit' => '2', 'name' => 'tyler', 'display_order' => '5', 'subscribers' => 0, ), 2 => array ( 'bit' => '4', 'name' => 'stephen', 'display_order' => '6', 'subscribers' => 0, ), 3 => array ( 'bit' => '8', 'name' => 'daniel', 'display_order' => '7', 'subscribers' => 0, ), 4 => array ( 'bit' => '16', 'name' => 'william', 'display_order' => '8', 'subscribers' => 0, ), 5 => array ( 'bit' => '32', 'name' => 'bobbys', 'display_order' => '9', 'subscribers' => 0, ), ), ), )
Long story short, I'm actually just trying to search this whole thing for say the name 'bobby' and get a simple true or false on whether that value exists anywhere in there.
print_r($myArray);
PHP Manual
<?php
$a = array ('a' => 'apple', 'b' => 'banana', 'c' => array ('x', 'y', 'z'));
print_r ($a);
?>
would give:
Array
(
[a] => apple
[b] => banana
[c] => Array
(
[0] => x
[1] => y
[2] => z
)
)
Not sure if this is what you are looking for...
print_r() gives you a visual representation while var_export() returns valid, executable php code. Manual: var_export()
You're assuming that arrays are only doubly-nested, when $retval[<something>]['groups'] is also an array. Use recursion to handle this instead of just adding levels upon levels.
It sounds like you need to reconsider what you are trying to do.
If you just want to see what is in your array so that you know how to get at a particular piece of data, then you're probabaly after print_r, var_export or similar as mentioned above.
print_r($retval);
If you want your php script to be able to work out on it's own whether 'bobby' is in the array, then you might have some more information that will help your search. For example, do you know the structure of your array and that you're searching for a name? If so, then you only need to check the strings that are in $array[$foo]['name']. You could adapt your code like so:
foreach($retval as $k=>$v) {
if ($v['name'] == 'bobby') {
echo "Bobby is at index $k";
}
}
PHP contains lots of functions for arrays, although these tend to be for single-dimension arrays.
P.S. Please edit the structure of your array to make it easier to read.
If your goal is to understand if a value is in any nested array you can do this:
foreach($retval as $vec){
if(in_array("bobby", $vec)
do something
Use a RecursiveArrayIterator wrapped in RecursiveIteratorIterator. The syntax will then be:
$arr = array('this is your complicated multi-dimensional array');
$iterator = new RecursiveIteratorIterator(new RecursiveArrayIterator($arr));
foreach($iterator as $key => $value){
echo '['.$key.'] => '.$value.'<br />';
}
You can even use $iterator->depth() to determine the depth of a current element.
I have two arrays of animals (for example).
$array = array(
array(
'id' => 1,
'name' => 'Cat',
),
array(
'id' => 2,
'name' => 'Mouse',
)
);
$array2 = array(
array(
'id' => 2,
'age' => 321,
),
array(
'id' => 1,
'age' => 123,
)
);
How can I merge the two arrays into one by the ID?
#Andy
http://se.php.net/array_merge
That was my first thought but it doesn't quite work - however array_merge_recursive might work - too lazy to check right now.
This does what Erik suggested (id no. as array key) and merges vlaues in $array2 to $results.
$results = array();
foreach($array as $subarray)
{
$results[$subarray['id']] = array('name' => $subarray['name']);
}
foreach($array2 as $subarray)
{
if(array_key_exists($subarray['id'], $results))
{
// Loop through $subarray would go here if you have extra
$results[$subarray['id']]['age'] = $subarray['age'];
}
}
First off, why don't you use the ID as the index (or key, in the mapping-style array that php arrays are imo)?
$array = array(
1 => array(
'name' => 'Cat',
),
2 => array(
'name' => 'Mouse',
)
);
after that you'll have to foreach through one array, performing array_merge on the items of the other:
foreach($array2 as $key=>$value) {
if(!is_array($array[$key])) $array[$key] = $value;
else $array[$key] = array_merge($array[key], $value);
}
Something like that at least. Perhaps there's a better solution?
<?php
$a = array('a' => '1', 'b' => array('t' => '4', 'g' => array('e' => '8')));
$b = array('c' => '3', 'b' => array('0' => '4', 'g' => array('h' => '5', 'v' => '9')));
$c = array_merge_recursive($a, $b);
print_r($c);
?>
array_merge_recursive — Merge two or more arrays recursively
outputs:
Array
(
[a] => 1
[b] => Array
(
[t] => 4
[g] => Array
(
[e] => 8
[h] => 5
[v] => 9
)
[0] => 4
)
[c] => 3
)
#Andy
I've already looked at that and didn't see how it can help merge multidimensional arrays. Maybe you could give an example.
#kevin
That is probably what I will need to do as I think the code below will be very slow.
The actual code is a bit different because I'm using ADOdb (and ODBC for the other query) but I'll make it work and post my own answer.
This works, however I think it will be very slow as it goes through the second loop every time:
foreach($array as &$animal)
{
foreach($array2 as $animal2)
{
if($animal['id'] === $animal2['id'])
{
$animal = array_merge($animal, $animal2);
break;
}
}
}
foreach ($array as $a)
$new_array[$a['id']]['name'] = $a['name'];
foreach ($array2 as $a)
$new_array[$a['id']]['age'] = $a['age'];
and this is result:
[1] => Array
(
[name] => Cat
[age] => 123
)
[2] => Array
(
[name] => Mouse
[age] => 321
)
<?php
$array1 = array("color" => "red", 2, 4);
$array2 = array("a", "b", "color" => "green", "shape" => "trapezoid", 4);
$result = array_merge($array1, $array2);
print_r($result);
?>
With PHP 5.3 you can do this sort of merge with array_replace_recursive()
http://www.php.net/manual/en/function.array-replace-recursive.php
You're resultant array should look like:
Array (
[0] => Array
(
[id] => 2
[name] => Cat
[age] => 321
)
[1] => Array
(
[id] => 1
[name] => Mouse
[age] => 123
)
)
Which is what I think you wanted as a result.
I would rather prefer array_splice over array_merge because of its performance issues, my solution would be:
<?php
array_splice($array1,count($array1),0,$array2);
?>
$new = array();
foreach ($array as $arr) {
$match = false;
foreach ($array2 as $arr2) {
if ($arr['id'] == $arr2['id']) {
$match = true;
$new[] = array_merge($arr, $arr2);
break;
}
}
if ( !$match ) $new[] = $arr;
}