Map array with initial letter in PHP - php

I wish to group a word list in an array with the initial letter.
function alpha($str) {
$result[substr($str,0,1)] = $str;
return $result;
}
$a = ['abc','cde','frtg','acf'];
$b = array_map('alpha', $a);
print_r($b);
What I need:
Array
(
[a] => abc,acf
[c] => cde
[f] => frtg
)
What I get:
Array
(
[0] => Array
(
[a] => abc
)
[1] => Array
(
[c] => cde
)
[2] => Array
(
[f] => frtg
)
[3] => Array
(
[a] => acf
)
)

How about that :
$answer = [];
$a = ['abc','cde','frtg','acf'];
foreach($a as $word){
$key = substr($word,0,1);
if (isset($answer[$key])){
$answer[$key] .= "," . $word;
} else {
$answer[$key] = $word;
}
}

Just add a variable $c and loop over arrays of array using two foreach and group by alphabet...
function alpha($str) {
$result[substr($str,0,1)] = $str;
return $result;
}
$a = ['abc','cde','frtg','acf'];
$b = array_map('alpha', $a);
#print_r($b);
$c = [];
foreach ($b as $key => $values) {
foreach ($values as $key => $value) {
if(!isset($c[$key])){
$c[$key]=$value;
}else{
$c[$key].= "," . $value;
}
}
}
echo "<PRE>";
print_r($c);
Outupt:
Array
(
[a] => abc,acf
[c] => cde
[f] => frtg
)

The function array_map maps to the original indexes but you want new indexes and an altered array, if there are more values with the same initial character. Therefore array_map don't work for you. You could create your new array this way:
$a = ['abc','cde','frtg','acf'];
$b = Array();
$c = Array();
foreach( $a as $v )
{
// multidimensional array
$b[substr($v,0,1)][] = $v;
// comma separated string
$c[substr($v,0,1)] = (isset($c[substr($v,0,1)])) ?
$c[substr($v,0,1)].",$v" : $v;
}

If the first character can also be multibyte Unicode such as ° or €, mb_substr() must be used! Solution with foreach:
$result = [];
$a = ['abc','€de','frtg','acf'];
foreach($a as $word){
$key = mb_substr($word,0,1);
$result[$key] = array_key_exists($key,$result)
? ($result[$key].",".$word)
: $word
;
}
Solution with array_reduce():
$result = array_reduce($a,function($carry,$item){
$key = mb_substr($item,0,1);
$carry[$key] = array_key_exists($key,$carry) ? ($carry[$key].",".$item) : $item;
return $carry;
},[]);
var_export($result);
Output:
array (
'a' => 'abc,acf',
'€' => '€de',
'f' => 'frtg',
)

I think your intention is to store each word into arrays according to its first letter. In this case, the multidimensional array is the right choice.
$array = ['abc','cde','frtg','acf'];
$new_array = array();
foreach($array as $v){
$letter = substr($v,0,1);
if(!isset($new_array[$letter])) {$new_array[$letter] = array();}
array_push($new_array[$letter], $v);
}
print_r($new_array);

Related

Get only Numeric values from Array in PHP

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); }
}

Concat values of array with same key

I want to concat values of array with same key
Example:
[0] => Array
(
[0] => A
[1] => XYZ
)
[1] => Array
(
[0] => B
[1] => ABC
)
[2] => Array
(
[0] => A
[1] => LMN
)
[3] => Array
(
[0] => B
[1] => PQR
)
)
Expected output:
[0] => Array
(
[0] => A
[1] => XYZ,LMN
)
[1] => Array
(
[0] => B
[1] => ABC,PQR
)
)
A simple solution uses the PHP function array_reduce():
// The input array you posted in the question
$input = array(
array('A', 'XYZ'),
array('B', 'ABC'),
array('A', 'LMN'),
array('B', 'PQR'),
);
// Reduce the array to a new array that contains the data aggregated as you need
$output = array_reduce(
// Process each $item from $input using a callback function
$input,
// The callback function processes $item; the partial result is $carry
function (array $carry, array $item) {
// Extract the key into a variable
$key = $item[0];
// If the key was encountered before
// then a partial entry already exists in $carry
if (isset($carry[$key])) {
// Append the desired value to the existing entry
$carry[$key][1] .= ','.$item[1];
} else {
// Create a new entry in $carry (copy $item to key $key for quick retrieval)
$carry[$key] = $item;
}
// Return the updated $carry
return $carry;
},
// Start with an empty array (it is known as $carry in the callback function)
array()
);
// $output contains the array you need
Try this:
$final = array();
foreach ($array_items as $item)
{
$key = $item[0];
$found_index = -1;
for ($i=0; $i<count($final); $i++)
{
if ($key == $final[$i][0])
{
$found_index = $i;
break;
}
}
if ($found_index == -1)
{
$final_item = array();
$final_item[0] = $key;
$final_item[1] = $item[1];
$final[] = $final_item;
}
else
{
$final[$found_index][1] .= ",".$item[1];
}
}
We create a new array $final, and loop through your old array $array_items. For each item, we see if there is already an item in $final that has the same [0] index. If it doesn't exist, we create it and add the initial string to the [1] index. If it does exist, we just have to add the string onto the end of the [1] index.
Try it, substituting $array_items for whatever your array is called, let me know if it works.
Check my solution. It should work fine. I hope it will help you much.
$result = $passed_keys = $extended_arr = [];
foreach ($arr as $k => $value) {
for($i = $k + 1; $i < count($arr); $i++){
if ( $value[0] == $arr[$i][0] ){ // compare each array with rest subsequent arrays
$key_name = $value[0];
if (!array_key_exists($key_name, $result)){
$result[$key_name] = $value[1] .",". $arr[$i][1];
} else {
if (!in_array($i, $passed_keys[$key_name])) {
$result[$key_name] .= ",". $arr[$i][1];
}
}
$passed_keys[$key_name][] = $i; // memorizing keys that were passed
}
}
}
array_walk($result, function($v, $k) use(&$extended_arr){
$extended_arr[] = [$k, $v];
});
The result is in $extended_arr
My solution, creates a custom key which makes identifying the letter much easier. This removes the need to continuously iterate through each array, which can become a major resources hog.
<?php
$inital_array = array(
array('A','XYZ'),
array('B','ABC'),
array('A','LMN'),
array('B','PQR')
);
$concat_array = array();
foreach($inital_array as $a){
$key = $a[0];
if( !isset($concat_array[$key]) ){
$concat_array[$key] = array($key,'');
}
$concat_array[$key][1] .= (empty($concat_array[$key][1]) ? '' : ',').$a[1];
}
$concat_array = array_values($concat_array);
echo '<pre>',print_r($concat_array),'</pre>';

How to concatenate two Array keys?

I would like to know if there is a way to convert two Array keys into one Array key?
As an example the Array would look like:
[0] => '12345'
[1] => 'New'
[2] => 'York'
how can I combine [1] => 'New' and [2] => 'York' into [1] => 'New York'?
All I was found is array_merge that combines two Arrays. Even on how to concaternate two Array keys I could not find anything.
Thanks alot.
You can try :
$data = array(12345,"New","York");
echo concat($data, array(1,2)); //New York
//or
$data = array(12345,"New","York");
print_r(concatArray($data, array(1,2)));
Output
Array
(
[0] => 12345
[1] => New York
)
Function Used
function concat($array, $keys , $glue = " ") {
$values = array_intersect_key($array, array_flip($keys));
return implode($glue, $values);
}
function concatArray($array, $keys, $glue = " ") {
$last = null;
foreach ( $array as $key => &$value ) {
if (in_array($key, $keys)) {
if ($last === null) {
$last = $key;
continue;
}
$array[$last] .= $glue . $value;
unset($array[$key]);
}
}
return $array;
}
Here's a hint ;)
$new = $array[1] . ' ' . $array[2];
$array[1] = $new;
unset($array[2]);

Array Implode in php

I have an array of the following format:
$var = Array
(
[0] => Array
(
[name] => Harry
)
[1] => Array
(
[name] => Wayne
)
)
Array
(
[0] => Array
(
[name] => Wayne
)
I want to implode this array such that i get it in the format:
Harry,Wayne
Wayne
From What I have Tried I am getting it in format:
Harry,Wayne
Harry,Wayne,Wayne
What I have Tried (Not important as its wrong)
foreach($var as $a){
foreach($a as $b){
}$c[] = $b
}
$imp = implode(',',$c);
$var is fetched from database using fetch_array.
$this->db->select('name');
$this->db->where('id', $Id);
$this->db->from('info');
$row = $this->db->get();
$var = $row->result_array();
where $Id is array containing certain user ids.
foreach($var as $a)
{
unset($temp);
foreach($a as $b)
{
$temp[] = $b['name'];
}
$c[] = implode(",", $temp);
}
// output all the names
foreach ($c as $csvNames)
{
echo $csvNames;
}
Try this.
foreach($var as $a){
$m = '';
$delim = '';
foreach($a as $k){
$m .= $delim . $k['name'];
$delim = ',';
}
$c[] = $m;
}
foreach($c as $d){
echo $d;
}
Please ignore those hard-coded loops. There is a recursive function for it.
array_walk_recursive($var, create_function('$val, $key', 'array_push($obj, $val);'), &$output);
echo implode(",",$output);

php multidimensional array from known key values

I have a collection of keys in this massive flat single array I would like to basically expand that array into a multidimensional one organized by keys - here is an example:
'invoice/products/data/item1'
'invoice/products/data/item2'
'invoice/products/data/item2'
=>
'invoice'=>'products'=>array('item1','item2','item3')
how can I do this - the length of the above strings are variable...
Thanks!
$src = array(
'invoice/products/data/item1',
'invoice/products/data/item2',
'invoice/products/data/item2',
'foo/bar/baz',
'aaa/bbb'
);
function rsplit(&$v, $w)
{
list($first, $tail) = explode('/', $w, 2);
if(empty($tail))
{
$v[] = $first;
return $v;
}
$v[$first] = rsplit($v[$first], $tail);
return $v;
}
$result = array_reduce($src, "rsplit");
print_r($result);
Output is:
Array (
[invoice] => Array
(
[products] => Array
(
[data] => Array
(
[0] => item1
[1] => item2
[2] => item2
)
)
)
[foo] => Array
(
[bar] => Array
(
[0] => baz
)
)
[aaa] => Array
(
[0] => bbb
)
)
Something along these lines: (Didn't test it though!) Works now ;)
$data = array();
$current = &$data;
foreach($keys as $value) {
$parts = explode("/", $value);
$parts_count = count($parts);
foreach($parts as $i => $part) {
if(!array_key_exists($part, $current)) {
if($i == $parts_count - 1) {
$current[] = $part;
}
else {
$current[$part] = array();
$current = &$current[$part];
}
}
else {
$current = &$current[$part];
}
}
$current = &$data;
}
$keys beeing the flat array.
Although it's not clear from your question how the "/" separated strings will map to an array, the basic approach will probably be something like this:
$result = array();
$k1 = $k2 = '';
ksort($yourData); // This is the key (!)
foreach ($yourData as $k => $v) {
// Use if / else if / else if to watch for new sub arrays and change
// $k1, $k2 accordingly
$result[$k1][$k2] = $v;
}
This approach uses the ksort to ensure that keys at the same "level" appear together, like this:
'invoice/products/data1/item1'
'invoice/products/data1/item2'
'invoice/products/data2/item3'
'invoice/products2/data3/item4'
'invoice/products2/data3/item5'
Notice how the ksort corresponds to the key grouping you're aiming for.

Categories