I have an array from array_diff function and it looks like below:
Array
(
[0] => world
[1] => is
[2] => a
[3] => wonderfull
[5] => in
[6] => our
)
As you can see, we have a gap between the keys #3 and #5 (i.e. there is no key #4).
How can I split that array into 2 parts, or maybe more if there are more gaps?
The expected output would be:
Array
(
[0] => Array
(
[0] => world
[1] => is
[2] => a
[3] => wonderfull
)
[1] => Array
(
[0] => in
[1] => our
)
)
You can use old_key,new_key concept to check that there difference is 1 or not? if not then create new index inside you result array otherwise add the values on same index:-
<?php
$arr = Array(0 => 'world',1 => 'is',2 => 'a',3 => 'wonderfull',5 => 'in',6 => 'our');
$new_array = [];
$old_key = -1;
$i = 0;
foreach($arr as $key=>$val){
if(($key-$old_key) ==1){
$new_array[$i][] = $val;
$old_key = $key;
}
if(($key-$old_key) >1){
$i++;
$new_array[$i][] = $val;
$old_key = $key;
}
}
print_r($new_array);
https://3v4l.org/Yl9rp
You can make use of the array internal pointer to traverse the array.
<?php
$arr = Array(0=>"world",1=>"is",2=>"a",3=>"wonderfull",5=>"in",6=>"our");
print_r($arr);
$result = Array();
$lastkey;
while($word = current($arr))
{
$key = key($arr);
if(isset($lastkey) && $key == $lastkey + 1)
{
$result[count($result) - 1][] = $word;
}
else
{
$result[] = Array($word);
}
$lastkey = $key;
next($arr);
}
print_r($result);
?>
This task is a perfect candidate for a reference variable. You unconditionally push values into a designated "bucket" -- in this case a subarray. You only conditionally change where that bucket is in the output array.
There are two important checks to make when determining if a new incremented key should be generated:
if it is not the first iteration and
the current key minus (the previous key + 1) does not equal 0.
Code: (Demo)
$nextKey = null;
$result = [];
foreach ($array as $key => $val) {
if ($nextKey === null || $key !== $nextKey) {
unset($ref);
$result[] = &$ref;
}
$ref[] = $val;
$nextKey = $key + 1;
}
var_export($result);
This solution generates an indexed array starting from zero with my sample input and uses only one if block. In contrast, AliveToDie's solution generates a numerically keyed array starting from 1 and uses two condition blocks containing redundant lines of code.
Here is my array:
$var = array('a', 'b');
Now I want to define a range for each key. For example:
5 keys set on each value of array:
echo $var[0]; // output: a
echo $var[1]; // output: a
echo $var[2]; // output: a
echo $var[3]; // output: a
echo $var[4]; // output: a
echo $var[5]; // output: b
echo $var[6]; // output: b
echo $var[7]; // output: b
echo $var[8]; // output: b
echo $var[9]; // output: b
In fact I want something like this:
$var = array( '0'=>'a', '1'=>'a', '2'=>'a', '3'=>'a', '4'=>'a',
'5'=>'b', '6'=>'b', '7'=>'b', '8'=>'b', '9'=>'b' );
But in reality I can not define a rage of keys for each value, because the values are too much. It should be noted that I can implement it via if-else statement (without array), But in this case, performance will drop dramatically. something like this:
if (0 <= $i <=4) { $var = 'a'; }
elseif (5 <= $i <=9) { $var = 'b'; }
But as I said, the values are too much and I can not define a range for each value manually. So there is any solution ? (set 5 keys for each value dynamically)
$arr = array('a', 'b');
$i = 6; // for e.g.
$var = $arr[floor($i/5)];
// output: b
This should work for you:
Just loop through your array and array_fill() your result array with each value as many times as you want, e.g.
<?php
$var = array('a', 'b');
$amount = 5;
$result = [];
foreach($var as $k => $v)
$result = $result + array_fill($k*$amount, $amount, $v);
print_r($result);
?>
output:
Array
(
[0] => a
[1] => a
[2] => a
[3] => a
[4] => a
[5] => b
[6] => b
[7] => b
[8] => b
[9] => b
)
$var = array( '0'=>'a', '1'=>'b');
$new_array = array();
foreach ($var as $key => $value) {
for($i = 0 ; $i < 5 ; $i++){
$new_array[] = $value;
}
}
echo '<pre>';
print_r($new_array);
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>';
I have an array
Array
(
[0] => 123
[1] => 1244
[2] => 34124
[3] => 123
)
is there a loop that will check if the values in my array are equal to each other?
this will give you the count of each value
$array = array("123", "1244","34124","123");
$cnt_array = array_count_values($array)
echo "<pre>";
print_r($cnt_array);
$res = array();
foreach($cnt_array as $key=>$val){
if($val == 1){
$res[$key] = 'unique';
}
else{
$res[$key] = 'duplicate';
}
}
echo "<pre>";
print_r($res);
I have 2 arrays in PHP. One of them holds a list of dates, the other a list of numbers.
Array1
(
[0] => 2010-06-14
[1] => 2010-06-14
[2] => 2010-06-14
[3] => 2014-01-26
[4] => 2014-01-26
)
Array2
(
[0] => 120
[1] => 100
[2] => 60
[3] => 140
[4] => 30
)
The value [0] in Array2 belongs with the date [0] in Array1. What I am trying to do is add all of the values in Array2 together, based on the date. Any dates that match should have their values added together. So for example at the end I would like something like:
$date = 2010-06-14;
$value = 280;
$date = 2014-01-26;
$value = 170;
...and so on.
I've searched though the site but was unable to find exactly what I needed. Any help would be appreciated...
You can iterate $values, and get the corresponding date from $dates to use as the key in your result array.
foreach ($values as $key => $value) {
$result[$dates[$key]] = $value + ($result[$dates[$key]] ?? 0);
}
The output will be like this:
array (size=2)
'2010-06-14' => int 280
'2014-01-26' => int 170
$sum=0; // New Element
$Array3[][]=0; // New 2D array
$p=0; // Counter for 2D array
for($i=0;$i<5;$i++) // Single loop for traversing
{
$date=Array1[$i]; // Start for a date
while($date==Array1[$i]){ // For for Similar date
$sum=$sum+Array2[$i]; // Adding values of similar date
$i++; // Increment array
}
$Array3[$p]["date"]=$date; // Array3 date element
$Array3[$p]["sum"]=$sum; // Array4 date element
$i--; // Reducing a value which is incremented in while loop
}
Array3 is like
Array3
(
[0] => array( 'date' => " ",'sum' => " ")
[1] => array( 'date' => " ",'sum' => " ")
)
Are you trying to count all of the values in Array2 that have an entry in Array1 that matches some predefined target value?
If so, this for loop version should work:
private function forLoopVersion($array1, $array2, $target) {
$result = 0;
for ($i = 0; $i < count($array1); ++$i) {
if ($array1[$i] == $target) {
$result += $array2[$i];
}
}
return $result;
}
Also, this foreach loop version might work, but I do not know if the $key for $array1 can be used to index an element in $array2. You could try it:
private function foreachLoopVersion($array1, $array2, $target) {
$result = 0;
foreach ($array1 as $key => $value) {
if ($value == $target) {
$result += $array2[$key];
}
}
return $result;
}
$newArray = array();
for($i = 0; $i < count(Array1); $i++) {
$newArray[$Array1[$i]] = $Array2[$i];
}
echo $newArray[$date1] + $newArray[$date2];
Put the dates as keys to for easy math.