Inserting an item after specific array pattern - php

I would like to insert an item after a specific pattern. In my case I would like to insert x after every second a in an array. After six'th a my code does not work properly:
$array = array("a","a","a","a","a","a","b","a","a");
$out = array();
foreach ($array as $key=>$value){
$out[] = $value; // add current letter to new array
if($value=='a' && $array[$key-1]=='a' && $out[$key] !='x'){ // check if current and last letter are a
$out[] = 'x'; // if so add an x to the array
}
}
print_r($out);

Correct answer at the end
Is it that what are you looking for?
<?php
$array = array("a","a","a","a","a","a","b","a","a");
foreach ($array as $key => $value){
if ($key == 0 || $key == 1) {
$array[$key] = $value;
} elseif($array[$key-1] == 'a' && $array[$key-2] == 'a' && $array[$key] == 'a') {
$array[$key] = 'x';
} else {
$array[$key] = $value;
}
}
$count = count($array);
if ($array[$count-1] == 'a' && $array[$count-2] == 'a') {
$array[] = 'x';
}
print_r($array);
?>
If I understand correctly, after 2 a you want to put x into new array.
UPDATE
Please check now. There will be added a new element x if last two are a in array.
With exceptions, but still working:
<?php
$array = array("a","a","a","a","a","a","b","a","a");
foreach ($array as $key => $value){
if($array[$key-1] == 'a' && $array[$key-2] == 'a' && $array[$key] == 'a') {
$array[$key] = 'x';
}
}
$count = count($array);
if ($array[$count-1] == 'a' && $array[$count-2] == 'a') {
$array[] = 'x';
}
print_r($array);
?>
UPDATE - Correct code
I think code below will fit all your needs:
<?php
$arr = array("a","w","a","d","a","a","b","a","a", "w");
$arr_count = count($arr);
for ($i = 0; $i < $arr_count; $i++){
if (!empty($arr[$i+1]) && $arr[$i] == $arr[$i+1]) {
$first_half = array_slice($arr, 0, $i+2);
$second_half = array_slice($arr, $i+2, $arr_count);
if (count($second_half) > 0) {
$arr = array_merge($first_half, ["x"], $second_half);
}
}
}
$count = count($arr);
if ($arr[$count-1] == 'a' && $arr[$count-2] == 'a') {
$arr[] = 'x';
}
print_r($arr);
?>

As it was mentioned in the comment, you sure can use regular expression in this particular situation:
$pattern = '/a{2}/';
$replacement = '$0x';
$out = str_split(preg_replace(
$pattern,
$replacement,
implode('', $array)
));
Basically, we gluing the characters together (using implode) to form the string and then replacing every "aa" with "aax". After that we split string back to the array using str_split.
Here is demo.

Related

PHP How to merge array element with next while maintaining order?

$array = ['coke.','fanta.','chocolate.'];
foreach ($array as $key => $value) {
if (strlen($value)<6) {
$new[] = $value." ".$array[$key+1];
} else {
$new[] = $value;
}
}
This code doesn't have the desired effect, in fact it doesn't work at all. What I want to do is if an array element has string length less than 5, join it with the next element. So in this case the array should turn into this:
$array = ['coke. fanta.','chocolate.'];
$array = ['coke.','fanta.','chocolate.', 'candy'];
$new = [];
reset($array); // ensure internal pointer is at start
do{
$val = current($array); // capture current value
if(strlen($val)>=6):
$new[] = $val; // long string; add to $new
// short string. Concatenate with next value
// (note this moves array pointer forward)
else:
$nextVal = next($array) ? : '';
$new[] = trim($val . ' ' . $nextVal);
endif;
}while(next($array));
print_r($new); // what you want
Live demo
With array_reduce:
$array = ['coke.', 'fanta.', 'chocolate.', 'a.', 'b.', 'c.', 'd.'];
$result = array_reduce($array, function($c, $i) {
if ( strlen(end($c)) < 6 )
$c[key($c)] .= empty(current($c)) ? $i : " $i";
else
$c[] = $i;
return $c;
}, ['']);
print_r($result);
demo
<pre>
$array = ['coke.','fanta.','chocolate.'];
print_r($array);
echo "<pre>";
$next_merge = "";
foreach ($array as $key => $value) {
if($next_merge == $value){
continue;
}
if (strlen($value)<6) {
$new[] = $value." ".$array[$key+1];
$next_merge = $array[$key+1];
} else {
$new[] = $value;
}
}
print_r($new);
</pre>
Updated Code after adding pop after chocolate.
<pre>
$array = ['coke.','fanta.','chocolate.','pop'];
print_r($array);
echo "<br>";
$next_merge = "";
foreach ($array as $key => $value) {
if($next_merge == $value){
continue;
}
if (strlen($value)<6 && !empty($array[$key+1])) {
$new[] = $value." ".$array[$key+1];
$next_merge = $array[$key+1];
} else {
$new[] = $value;
}
}
print_r($new);
<pre>
You need to skip the iteration for the values that you have already added.
$array = ['coke.', 'fanta.', 'chocolate.'];
$cont = false;
foreach ($array as $key => $value) {
if ($cont) {
$cont = false;
continue;
}
if (strlen($value) < 6 && isset($array[$key+1])) {
$new[] = $value.' '.$array[$key+1];
$cont = true;
}
else {
$new[] = $value;
}
}
print_r($new);

How to get all values between two array values in php?

How can I find all values between two array items (including start and end value)?
Example:
array('3X' => '3X','EX'=> 'EX','VG'=>'VG','G'=>'G','F'=>'F','P'=>'P')
Input: $arr, 'EX', 'F'
Output: 'EX', 'VG', 'G', 'F'
Thanks in advance..
$array = array('3X' => '3X','EX'=> 'EX','VG'=>'VG','G'=>'G','F'=>'F','P'=>'P');
$start = "3X";
$end ="F";
$new_array = [];
$i=0;$go=false;
foreach ($array as $element) {
if($go){
$new_array[$i] = $element;
$i++;
}
if($element==$start){
$go = true;
}
if($element==$end){
$go = false;
}
}
$total_elems_new = count($new_array);
unset($new_array[$total_elems_new-1]);
print_r($new_array);
Testeed on PHP 5.6
Try:
$arr = array('3X' => '3X','EX'=> 'EX','VG'=>'VG','G'=>'G','F'=>'F','P'=>'P');
function findValuesBetweenTwoItems($arr, $start, $end) {
$result = [];
$has_started = false;
foreach ( $arr as $item->$value ) {
if( ( $item != $end && $has_started ) || $item == $start) {
array_push($result, $value);
$has_started = true;
}
if( $item == $end ) {
array_push($result, $value);
return $result;
}
}
$my_values = findValuesBetweenTwoItems($arr, 'EX', 'F');
var_dump($my_values);
Try this:
$array = array('3X' => '3X','EX'=> 'EX','VG'=>'VG','G'=>'G','F'=>'F','P'=>'P');
$arrayKeys = array_keys($array);
$input1 = '3X';
$input2 = 'F';
if(in_array($input1,$array) && in_array($input2,$array)) {
if (array_search($input1, array_keys($array)) >= 0) {
if (array_search($input2, array_keys($array)) >= 0) {
if (array_search($input1, array_keys($array)) < array_search($input2, array_keys($array))) {
echo "Keys in between: ";
for ($i = array_search($input1, array_keys($array)); $i <= array_search($input2, array_keys($array)); $i++) {
echo $array[$arrayKeys[$i]] . ", ";
}
} else {
echo "Keys in between: ";
for ($i = array_search($input2, array_keys($array)); $i <= array_search($input1, array_keys($array)); $i++) {
echo $array[$arrayKeys[$i]] . ", ";
}
}
} else {
echo "Value not found!";
}
} else {
echo "Value not found!";
}
} else{
echo "Value not found!";
}
$from = 'EX';
$to = 'F';
$result = null;
$state = 0;
foreach ($a as $k => $v) {
if (($state == 0 && $from === $v) || ($state == 1 && $to === $v))
$state++;
if ($state && $state < 3)
$result[$k] = $v;
elseif ($state >= 2)
break;
}
if ($state != 2)
$result = null;
The loop searches for the first occurrence of $from, if $state is 0 (initial value), or the first occurrence of $to, if $state is 1. For other values of $state, the loop stops processing.
When either $from, or $to is found, $state is incremented. The values are stored into $result while $state is either 1 ($from is found), or 2 ($to is found).
Thus, $state == 2 means that both values are found, and $result contains the values from the $a array between $from and $to. Otherwise, $result is assigned to null.

Comma separated string to parent child relationship array php

I have a comma separated string like
$str = "word1,word2,word3";
And i want to make a parent child relationship array from it.
Here is an example:
Try this simply making own function as
$str = "word1,word2,word3";
$res = [];
function makeNested($arr) {
if(count($arr)<2)
return $arr;
$key = array_shift($arr);
return array($key => makeNested($arr));
}
print_r(makeNested(explode(',', $str)));
Demo
function tooLazyToCode($string)
{
$structure = null;
foreach (array_reverse(explode(',', $string)) as $part) {
$structure = ($structure == null) ? $part : array($part => $structure);
}
return $structure;
}
Please check below code it will take half of the time of the above answers:
<?php
$str = "sports,cricket,football,hockey,tennis";
$arr = explode(',', $str);
$result = array();
$arr_len = count($arr) - 1;
$prev = $arr_len;
for($i = $arr_len; $i>=0;$i--){
if($prev != $i){
$result = array($arr[$i] => $result);
} else {
$result = array ($arr[$i]);
}
$prev = $i;
}
echo '<pre>',print_r($result),'</pre>';
Here is another code for you, it will give you result as you have asked :
<?php
$str = "sports,cricket,football,hockey,tennis";
$arr = explode(',', $str);
$result = array();
$arr_len = count($arr) - 1;
$prev = $arr_len;
for($i = $arr_len; $i>=0;$i--){
if($prev != $i){
if($i == 0){
$result = array($arr[$i] => $result);
}else{
$result = array(array($arr[$i] => $result));
}
} else {
$result = array ($arr[$i]);
}
$prev = $i;
}
echo '<pre>',print_r($result),'</pre>';

Key exist in complexe array

I would like to test if the key of an associative array exist in my $_POST.
my $_POST is like that:
$_POST["balle"]["x"] = 5;
$_POST["balle"]["y"] = 5;
$_POST["balle"]["z"] = 5;
or like that by example:
$_POST["p1"][1]["vit"] = 7;
$_POST["p1"][1]["angle"] = 32;
$_POST["p2"][2]["vit"] = 17;
$_POST["p2"][2]["angle"] = 2;
the values don't matter but I must check how are my $_POST keys.
I don't understand how i can test recursivly that because the $_POST can change and have differents forms.
I have try this:
function Check_post($new, $arr)
{
echo "Init<br/>";
$res = true;
if (is_array($new))
{
foreach ($new as $key => $value)
{
if (!in_array($key, $arr))
{
echo "Fail $key";
print_r($arr);
return (false);
}
$res = $res & Check_post($new[$key], $arr[$key]);
}
}
else
$res = in_array($new, $arr);
echo "MY RESULT";
var_dump($res);
return ($res);
}
$b = array();
$b["balle"] = array("x", "y", "z");
$post = array();
$post["balle"] = array();
$post["balle"]["x"] = 50;
$post["balle"]["y"] = 50;
$post["balle"]["z"] = 50;
echo "<pre>";
print_r($b);
echo "</pre><pre>";
print_r($post);
echo "</pre>";
Check_post($b, $post);
but i got "Fail balle". my $post variable is to simulate the real $_POST and for make it easier to test.
EDIT:
The function should work like that:
1) test if "balle" exist in $post
2) "balle" exist so recursive call
3) test if "x" exist in $post["balle"](recursive)
4) test if "y" exist in $post["balle"](recursive)
5) test if "z" exist in $post["balle"](recursive)
6) all existe so $res = true
EDIT:
I finaly editet the whole function:
function Check_post($needle, $haystack)
{
if(is_array($needle)){
foreach ($needle as $key => $element){
$result = true;
if($result = (array_key_exists($key, $haystack) || array_key_exists($element, $haystack))){
$key = (isset($haystack[$key]) ? $key : $element);
if(is_array($haystack[$key]))
$result = Check_post($element, $haystack[$key]);
}
if(!$result){
return false;
}
}
return $result;
}else {
return array_key_exists($needle, $haystack);
}
}
Now it should work as you want it
Example:
$_POST["balle"]["x"] = 5;
$_POST["balle"]["y"] = 5;
$_POST["balle"]["z"] = 5;
$b = array();
$b["balle"] = array("x", "y", "z");
var_dump(Check_post($b, $_POST)); //returns true
$b["balle"] = array("x", "y", "z", "b");
var_dump(Check_post($b, $_POST)); //returns false
The in_array function you're using checks if $key is contained in $arr as a value. If I got you right, you want to check if there is the same key in $arr instead. Use array_key_exists($key, $arr) for this.
Try this
$_POST["p1"][1]["vit"] = 7;
$_POST["p1"][1]["angle"] = 32;
$_POST["p2"][2]["vit"] = 17;
$_POST["p2"][2]["angle"] = 2;
$needle = "2";
$samp = Check_post($_POST,$needle);
echo $samp;
function Check_post($array,$needle)
{
if(is_array($array))
{
foreach($array as $key=>$value)
{
if($key == $needle)
{
echo $key." key exists ";
}
else
{
if(is_array($value))
{
check_post($value,$needle);
}
}
}
}
}
Demo

Removing a value from an array php

Is there an easier way to do so?
$array = array(1,57,5,84,21,8,4,2,8,3,4);
$remove = 21;
$i = 0;
foreach ($array as $value ){
if( $value == $remove)
unset($array[$i])
$i++;
}
//array: 1,57,5,84,8,4,2,8,3,4
The array_search answer is good. You could also arraydiff like this
$array = array(1,57,5,84,21,8,4,2,8,3,4);
$remove = array(21);
$result = array_diff($array, $remove);
If you want to delete the first occurrence of the item in the array, use array_search to find the index of the item in the array rather than rolling your own loop.
$array = array(1,57,5,84,21,8,4,2,8,3,4);
$remove = 21;
$index = array_search($remove, $array);
if (index !== false)
unset($array[$index]);
To remove all duplicates, rerun the search/delete so long as it finds a match:
while (false !== ($index = array_search($remove, $array))) {
unset($array[$index]);
}
or find all keys for matching values and remove them:
foreach (array_keys($array, $remove) as $key) {
unset($array[$key]);
}
This is a little cleaner:
foreach($array as $key => $value) {
if ($value == $remove) {
unset($array[$key]);
break;
}
}
UPDATE
Alternatively, you can place the non-matching values into a temp array, then reset the original.
$temp = array();
foreach($array as $key => $value) {
if ($value != $remove) {
$temp[$key] = $value;
}
}
$array = $temp;

Categories