Suppose there is array(1,2,2,3,4,4,5)
I want print in this format
A-1
B-2
B-2
A-3
B-4
B-4
A-5
One option would be an iterative approach which in which we iterate over your input array, keeping track of whether the current value differs from the previous value. If it does differ, then we switch the letter prefix from A to B, or vice-versa.
$array = array(1,2,2,3,4,4,5);
$output = array();
$flag = true;
$last_item = NULL;
foreach ($array as $item) {
if ($item != $last_item && $last_item != NULL) {
$flag = !$flag;
}
$prefix = $flag ? "A" : "B";
array_push($output, $prefix."-".$item);
$last_item = $item;
}
print_r($array);
print_r($output);
This prints:
Array
(
[0] => A-1
[1] => B-2
[2] => B-2
[3] => A-3
[4] => B-4
[5] => B-4
[6] => A-5
)
Solution 1.
If it is based on Even/Odd, You can use foreach
foreach($a as $v){
echo ($v % 2) ? 'A-'.$v : 'B-'.$v;echo ' ';
}
https://3v4l.org/XUafK
Solution 2.
Another way, if the same value repetations. You can use array_count_values
$a = array(1,2,2,3,4,4,5);
$b = array_count_values($a);
foreach($a as $v){
echo ($b[$v] > 1) ? 'B-'.$v : 'A-'.$v;
echo '<br/>';
}
Working example :- https://3v4l.org/hopM8
Try This
$arrayst = array(1,2,2,3,4,4,5);
foreach ( $arrayst as $number) {
if ($number % 2) {
echo "A-".$number." ";
}else{
echo "B-".$number." ";
}
}
Related
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);
Today in an interview i got the following question to solve without using any inbuilt function eg in_array and etc.I am able to solve the programme but they told me is there any better approach and also they told me the total code is only upto 7 lines.So can anyone tell me any better approach than this:-
<?php
$a = array(1,3,5,2,1,5,11,16);
$b = array(1,4,3,11,12,5,7,18);
$final = [];
for($i=0;$i<count($a);$i++){
$flag = 0;
if($i==0){
$final[] = $a[$i];
} else {
for($j=0;$j<count($final);$j++){
if($a[$i] == $final[$j]){
$flag = 1;
}
}
if($flag==0){
$final[] = $a[$i];
}
for($k=0;$k<count($final);$k++){
if($b[$i] == $final[$k]){
$flag = 1;
}
}
if($flag==0){
$final[] = $b[$i];
}
}
}
echo '<pre>';
print_r($final);
the result would be the final array which would contain unique array of both eg
Array ( [0] => 1 [1] => 3 [2] => 4 [3] => 5 [4] => 2 [5] => 11 [6] => 16 [7] => 18 )
Here is how you could do it without using built-in functions: Collect the values as keys (so they are unique), and then put those keys back as values in the final array:
$a = array(1,3,5,2,1,5,11,16);
$b = array(1,4,3,11,12,5,7,18);
foreach($a as $v) $keys[$v] = 1;
foreach($b as $v) $keys[$v] = 1;
foreach($keys as $k => $v) $final[] = $k;
echo '<pre>';
print_r($final);
See it run on eval.in.
Just set the key as the value and they will overwrite. If the arrays are the same length:
foreach($a as $k => $v) {
$final[$v] = $v;
$final[$b[$k]] = $b[$k];
}
If not, then do it for each array:
foreach(array($a, $b) as $c) {
foreach($c as $v) {
$final[$v] = $v;
}
}
The order and keys won't be the same, but that wasn't stated as a requirement.
Going through foreach loop for filter on my site I get array back like this:
Array
(
[21] => Blau
[24] => Azul
[28] => Blue
)
By choosing next filter another array will be created:
Array
(
[21] => Grün
[24] => Verde
[28] => Green
)
and so on...
What I what to do is merge values of these arrays on same keys. So it have to be look like this:
Array
(
[21] => Blau-Grün
[24] => Azul-Verde
[28] => Blue-Green
)
It worked with Uchiha's code. I made some changed inside my loop:
foreach (...){
//some logic before
$array[] = array();
$i = 0;
foreach($array as $k => $v){
$i++;
foreach($array[$k] as $key => $value){
if(array_key_exists($key, $array[$i])){
$result[$key] = $value . '-' . $array[$i][$key];
}
}
}
echo '<pre>' . print_r($result,true) . '</pre>';
}
$maxItems = max(count($blue),count($green));
for ($i = 0; $i < $maxItems; $i++) {
if (isset($blue[$i], $green[$i])) {
$combined[$i] = $blue[$i].'-'.$green[$i];
} else {
if (isset($blue[$i])) {
$combined[$i] = $blue[$i];
} else {
$combined[$i] = $green[$i];
}
}
}
You can use foreach along with array_key_exists as
foreach($arr1 as $key => $value){
if(array_key_exists($key, $arr2)){
$result[$key] = $value.'-'.$arr2[$key];
}
}
Fiddle
you can use array_map with a closure that joins the two values, e.g.
$joined = array_map(function($m, $n){ return $m . '-' . $n; }, $array1, $array2);
$foo = array(1 => "Bob", 2 => "Sepi");
$bar = array(1 => "sach", 2 => "john");
$foobar= array();
foreach ($foo as $key => $value) {
foreach ($bar as $key1 => $value1) {
if($key == $key1){
$foobar[] = $value."-".$value1;
}
}}
You can create a function, which takes both of arrays as parameter and identify which one has more elements, loop through and concat the string from another array at the same key.
$array1 = array(
'Blau',
'Azul',
'Blue'
);
$array2 = array(
'Grün',
'Verde',
'Green'
)
function mergeArray($array1, $array2){
$newArray = array();
if(count($array1) >= count($array2)){
foreach($array1 as $key => $value){
$newArray[] = $value . (array_key_exists($key, $array2) ? '-' . $array2[$key] : '');
}
} else {
foreach($array2 as $key => $value){
$newArray[] = $value . (array_key_exists($key, $array1) ? '-' . $array1[$key] : '');
}
}
}
$newArray = mergeArray($array1, $array2);
$newArray contains the result you expected.
here is simple and tested code
<?php
$a1=array(
1 => 'Blau',
2 => 'Azul',
3 => 'Blue'
);
$a2=array
(
1 => 'Grün',
2 => 'Verde',
4 => 'Green'
);
$a3=$a1 + $a2;
$a4=$a2 + $a1;
foreach($a3 as $key=>$val){
if($a4[$key] != $a3[$key]){
$a3[$key] = $a3[$key].' '.$a4[$key];
}
}
print_r($a3);
?>
I want to put my string (separated by comma) in 2 different arrays.
$str = 1,First,2,Second,3,Third,4,Forth,5,Fifth
My goal is to group the numbers and the text.
$number = {1,2,3,4,5)
$text = {first, second, third, forth, fifth}
I tried to use explode(), but I only be ale to create a single array.
This should work for you:
First explode() your string by a comma. Then you can array_filter() the numbers out. And at the end you can simply take the array_diff() from the $arr and the $numbers array.
<?php
$str = "1,First,2,Second,3,Third,4,Forth,5,Fifth";
$arr = explode(",", $str);
$numbers = array_filter($arr, "intval");
$text = array_diff($arr, $numbers);
?>
You can use explode() and array_map() over the results:
$str = '1,First,2,Second,3,Third,4,Forth,5,Fifth';
array_map(function($item) use (&$numbers, &$strings) {
if(is_numeric($item)) {
$numbers []= $item;
} else {
$strings []= $item;
}
}, explode(',', $str));
var_dump($numbers, $strings);
<?php
$str = array(1,'First',2,'Second',3,'Third',4,'Forth',5,'Fifth');
$letters =array();
$no = array();
for($i=0;$i<count($str);$i++){
if($i%2 ==0){
$letters[] = $str[$i];
}else{
$no[] = $str[$i];
}
}
print_r($no);
print_r($letters);
?>
May be this can help you
$str = '1,First,2,Second,3,Third,4,Forth,5,Fifth';
$array = explode(',',$str);
$number = array();
$string = array();
foreach($array as $val)
{
if(is_numeric($val))
{
$number[] = $val;
}
elseif(!is_numeric($val))
{
$string[] = $val;
}
}
echo $commNum = implode(',',$number); // These are strings
echo '<br/>'.$commStr = implode(',',$string); // These are strings
echo '<pre>';
print_r($number); // These are arrays
echo '<pre>';
print_r($string); // These are arrays
This should work for you.
$str = '1,First,2,Second,3,Third,4,Forth,5,Fifth';
$result = explode(',',$str);
$number = array();
$text = array();
foreach(explode(',',$str) as $key => $value){
if($key % 2 == 1){
$text[] = $value;
}elseif($key % 2 == 0){
$number[] = $value;
}
}
print_r($number);//Array ( [0] => 1 [1] => 2 [2] => 3 [3] => 4 [4] => 5 )
print_r($text);//Array ( [0] => First [1] => Second [2] => Third [3] => Forth [4] => Fifth )
and if your array is not consistent in this manner then some of these above answers are well suited for you like of Rizier123,hek2mgl,& Sunil's one
I'm updating my answer for your correspondent comments over Adrian
foreach(explode(',',$str) as $key => $value){
if(is_numeric($value)){
$number[] = $value;
}else{
$text[] = $value;
}
}
You can use explode, but you need apply some filter in this case is is_numeric:
<?php
$str = '1,First,2,Second,3,Third,4,Forth,5,Fifth, erewwrw , 6 ';
$array = explode(',', $str);
$array_numbers = array();
$array_letters = array();
for($i = 0; $i < count($array); $i++) {
if(is_numeric(trim($array[$i]))) {
$array_numbers[] = trim($array[$i]);
} else {
$array_letters[] = trim($array[$i]);
}
}
print_r($array_numbers);
print_r($array_letters);
?>
Output:
Array
(
[0] => 1
[1] => 2
[2] => 3
[3] => 4
[4] => 5
)
Array
(
[0] => First
[1] => Second
[2] => Third
[3] => Forth
[4] => Fifth
)
Assuming that your string contains number followed by string and so on,
following should be the solution.
Create two blank arrays: $numbers and $strings.
Just loop over the array and get even and odd elements.
Even elements should go to numbers array and odd elements should go to strings array.
$str = '1,First,2,Second,3,Third,4,Forth,5,Fifth';
$numbers = array();
$strings = array();
$temp = explode(',', $str);
$i=0;
foreach ($temp as $e) {
if ($i%2) {
$strings[] = $e;
}
else {
$numbers[] = $e;
}
++$i;
}
echo '<pre>';
print_r($numbers);
echo '</pre>';
echo '<pre>';
print_r($strings);
echo '</pre>';
After CURL'ing a page and creating a list of items in an array. I have no control over the markup. I'm trying to filter out the last remainder of items that don't follow the alphabet after the letter Z.
In this case I'd like to disregard indexes 7 and beyond.
Array
(
[0] => Apple
[1] => Acorn
[2] => Banana
[3] => Cucumber
[4] => Date
[5] => Zombify
[6] => Zoo // last item
[7] => Umbrella // disregard
[8] => Kangaroo // disregard
[9] => Apple // disregard
[10] => Star // disregard
[11] => Umbrella // disregard
[12] => Kangaroo // disregard
[13] => Apple // disregard
)
What I cannot figure out is the appropriate solution for the cutoff point at the letter Z.
$letters = range('A', 'Z');
foreach($listContent as $listItem) {
foreach($letters as $letter) {
if (substr($listItem, 0, 1) == $letter) {
$newArray[] = $listItem;
}
}
}
How about this:
$last= "A";
foreach($listContent as $listItem) {
$current = strtoupper(substr($listItem, 0,1));
// only add the element if it is alphabetically sorted behind the last element and is a character
if ($current < $last || $current < 'A' || $current > 'Z') break;
$last = $current;
$newArray[] = $listItem;
}
This will handle the updated array you posted. For instance, it will keep Zombie and Zoo, but then it will end.
$letters = range('A', 'Z');
$newArray = array();
foreach ($listContent as $listItem) {
$firstLetter = substr($listItem, 0, 1);
if (!in_array($firstLetter, $letters)) {
break; // edited to break instead of continue.
}
$position = array_search($firstLetter, $letters);
$letters = array_slice($letters, $position);
$newArray[] = $listItem;
}
Have tested this and works correctly - to my understanding of your requirement:
$letters = range('A', 'Z');
$item_prev_char = "";
foreach( $listContent as $listItem )
{
$item_first_char = substr($listItem, 0, 1);
if ( $item_prev_char <= $item_first_char )
{
foreach( $letters as $letter )
{
if ($item_first_char == $letter )
{
$new_array[] = $listItem;
$item_prev_char = $item_first_char;
echo $listItem."<br/>";
break;
}
}
}
}