PHP array remove all arrays under keyword if found - php

I have 30 lines of text and explode into arrays separate by "\n". the result as follows:
[1]=> string(121) "In recent years, the rapid growth"
[2]=> string(139) "information technology has strongly enhanced computer systems"
[3]=> string(89) "both in terms of computational and networking capabilities"
[4]=> string(103) "-------------------------"
[5]=> string(103) "these novel distributed computing scenarios"
.
.
[30]=> string(103) "these computer safety applications. end"
in this case, i need to remove all arrays below "-------------" and produce output as follows:
[1]=> string(121) "In recent years, the rapid growth"
[2]=> string(139) "information technology has strongly enhanced computer systems"
[3]=> string(89) "both in terms of computational and networking capabilities"
any idea how to do this? thanks.
solution of the problem by Michael
$i = 0;
$new_arr = array();
while ($array[$i] != "-------------------------") {
// Append lines onto the new array until the delimiter is found
$new_arr[] = $array[$i];
$i++;
}
print_r($new_arr);

Best solution:
Use array_search() and then truncate the array with array_splice():
$key = array_search("-------------------------", $array);
array_splice($array, $key);
Obvious solution:
You can loop over it copying the output to a new array. First example that comes to mind:
$i = 0;
$new_arr = array();
while ($array[$i] != "-------------------------") {
// Append lines onto the new array until the delimiter is found
$new_arr[] = $array[$i];
$i++;
}
print_r($new_arr);

for example
function getMyArray( $array ){
$myArray = array();
foreach( $array as $item ){
if ( $item == '-------------------------' ){ return $myArray; }
$myArray[] = $line;
}
return $myArray'
}

array_search
and unset
you can also use array_slice

You can use array_search to find the key of where its located.
from PHP.net:
<?php
$array = array(0 => 'blue', 1 => 'red', 2 => 'green', 3 => 'red');
$key = array_search('green', $array); // $key = 2;
?>
Once you have the key, you could do:
<?php
while($key < count($array) )
{
$array = unset($array[$key]);
$key++;
}
?>

foreach($array as $key => $value)
{
if($value == '-------------')
break;
else
$new_array[$key]=$value;
}

Related

How correctly to process an arrays?

There are two arrays:
$arr1 = ['word', 'tech', 'care', 'kek', 'lol', 'wild', 'regex'];
$arr2 = ['ord', 'ek', 'ol', 'ld', 'gex', 'ss'];
The number of elements in the second array is less than or equal to the first array.
Sort out the first array and the second array, if the elements of the second array are contained at the end of the elements of the first array, sort the array in this form:
Array
(
[0] => w_ord
[1] => tech
[2] => care
[3] => k_ek
[4] => l_ol
[5] => wi_ld
[6] => re_gex
)
Important: the elements of the second array are never repeated, and can go in any order. If in the second element there is no end of the element of the first array, then set the value of the element of the first array.
I do this:
foreach($arr2 as $val) {
$strrepl[$val] = "_".$val;
}
foreach($arr1 as $key => $val) {
$arr3[$key] = str_replace(array_keys($strrepl), $strrepl, $val);
}
print_r($arr3);
But I'm not sure that this is the right approach, what will you advise?
Hmm, let's see ... purely functional 'cause you know :D
function ends($str) {
return function($suffix) use($str) {
return mb_strlen($str) >= mb_strlen($suffix)
&& mb_substr($str, mb_strlen($suffix) * -1) === $suffix;
};
}
$result = array_map(function($item) use($arr2) {
$filter = ends($item);
$suffixes = array_filter($arr2, $filter);
if (empty($suffixes)) {
return $item;
}
// This only cares about the very first match, but
// is easily adaptable to handle all of them
$suffix = reset($suffixes);
return mb_substr($item, 0, mb_strlen($suffix) * -1) . "_{$suffix}";
}, $arr1);
Surprisingly, this one was quite fun to execute.
Since you went very specific on end of the element, I decided to use RegEx for that.
Here is my approach:
$arr1 = ['word', 'tech', 'care', 'kek', 'lol', 'wild', 'regex'];
$arr2 = ['ord', 'ek', 'ol', 'ld', 'gex', 'ss'];
foreach ($arr2 as $find) {
foreach ($arr1 as $key => $element) {
$arr1[$key] = preg_replace('/' . $find . '$/', '_' . $find, $element);
}
}
For every element of the second array (since they are not repeated), I go through every element of the first array and check if the value can be found at the end of the element of the second array using the $ anchor from RegEx which forces it to look it from the end of the string.
This way the $arr1 will have exactly what you expect.
[Edit]
Following the scape suggestion from #aefxx and improving variable names.
You can use preg_grep which is regex on arrays.
This code will also make sure it can output more than one matching word from $arr1.
$arr1 = ['word', 'chord', 'tech', 'care', 'kek', 'lol', 'wild', 'regex'];
$arr2 = ['ord', 'ek', 'ol', 'ld', 'gex', 'ss'];
$keys=[];
foreach($arr2 as $val){
$matches = preg_grep("/.+" . preg_quote($val) . "/", $arr1);
$keys = array_merge($keys, array_keys($matches)); // save keys of matched words
foreach($matches as $key => $m) $new[$val][] = str_replace($val, "_$val", $arr1[$key]);
}
$new['unmatched'] = array_diff_key($arr1, array_flip($keys)); // add unmatched words
var_dump($new);
Output:
array(6) {
["ord"]=>
array(2) {
[0]=>
string(5) "w_ord"
[1]=>
string(6) "ch_ord"
}
["ek"]=>
array(1) {
[0]=>
string(4) "k_ek"
}
["ol"]=>
array(1) {
[0]=>
string(4) "l_ol"
}
["ld"]=>
array(1) {
[0]=>
string(5) "wi_ld"
}
["gex"]=>
array(1) {
[0]=>
string(6) "re_gex"
}
["unmatched"]=>
array(2) {
[2]=>
string(4) "tech"
[3]=>
string(4) "care"
}
}
https://3v4l.org/gfUea
You can try this.I think it is easy to understand :
$arr1=['word','tech','care','kek','lol','wild','regex'];
$arr2=['ord','ek','ol','ld','gex','ss'];
foreach($arr1 as $key=>$fullword){
foreach($arr2 as $substr){
$arr1[$key]=preg_replace('/' . $substr . '$/', '_' . $substr, $fullword,-1,$count);
if($count) break;
}
}
i go throught the array of fullword and as soon as i find a match i stop the search.
Another approach can be to create complex regex beforehand (using implode and preg_quote for safety) and use it for replacement inside array_map callback:
$arr1 = ['word', 'tech', 'care', 'kek', 'lol', 'wild', 'regex'];
$arr2 = ['ord', 'ek', 'ol', 'ld', 'gex', 'ss'];
$regex = '/(' . implode('|', array_map('preg_quote', $arr2)) . ')$/';
$result = array_map(function ($word) use ($regex) {
return preg_replace($regex, '_$1', $word);
}, $arr1);
Here is the demo.

Php array value to keys

Hi let's say I have this array
array(2) {
[0]=>
string(9) "name|a-z+"
[1]=>
string(7) "id|0-9+"
}
Now I want a new array (or the same if possible) to be like this:
array(2) {
[name]=>
string(4) "a-z+"
[id]=>
string(4) "0-9+"
}
I think the solution implies explode and array_combine, but I am not good enough, can someone help me?
Thanks in advance.
function convert_my_array($arr){
$out = array();
foreach($arr as $obj){
$data = explode("|", $obj);
$out[$data[0]] = $data[1];
}
return $out;
}
Using the original array called $array here, loop through it set the values to what you want.
$newarray = array();
foreach ($array as $key=>$val) {
list($one, $two) = explode('|', $val);
$newarray[$one] = $two;
}

How to create an array using array_fill function in PHP?

I want to create an array like below
array(2) {
[0]=>
array(2) {
[0]=>
int(1)
[1]=>
int(0)
}
[1]=>
array(2) {
[0]=>
int(2)
[1]=>
int(0)
}
}
Here first element of the inner array will be incremental and second element will always be 0. The outer array length should be 30. I spent a lot of of time on it but couldn't solve it by my one.
Can any one of you help me ?
Thanks
You could do it using array_map() and range():
$o = array_map(function($a) { return array($a, 0); }, range(1, 30));
Demo
The array_fill() function creates an array where all elements are identical. You're asking for an array where the elements aren't all identical, so it's not something you can create simply by using array_fill()....
$array = array_fill(0, 2, array_fill(0, 2, 0));
array_walk($array, function(&$value, $key) { $value[0] = $key+1; });
Maybe you want something like this?
<?php
function initArray() {
$array = array();
for ($i = 1; $i <= 30; $i++) {
$array[] = array($i, 0);
}
return $array;
}
// now call the initArray() function somewhere you need it
$myFancyArray = initArray();
?>

change key of the multi-array

Have an array:
$a =array[
"param1"=>[]
"param2"=>[]
"param3"=>[]
]
function def($param){
return $param.date();
}
want return a new array
$a =array[
def(param1)=>[]
def(param2)=>[]
def(param3)=>[]
]
anybody know how to do this?
Do you mean something like this?
This is a pretty lengthy (and dirty) suggestion and there's probably a better way using one of PHP's array methods, but here goes:
$array = array('123' => 'should be 6', '14' => 'should be 5', '12' => 'should be 3');
$new_array = array();
foreach ($array as $key => $val) {
$key_exp = str_split($key);
$new_key = 0;
foreach ($key_exp as $key_int) $new_key += $key_int;
$new_array[$new_key] = $val;
}
Gives this output as expected:
array(3) {
[6]=>
string(11) "should be 6"
[5]=>
string(11) "should be 5"
[3]=>
string(11) "should be 3"
}
Note that you may, and probably will, run into key collisions using this method.
Like so:
$out_array = array_fill_keys(array_map(function($in) {
// do stuff you need
return $out;
}, array_keys($in_array)), array());

Simple PHP Recursion Test Failing

I am attempting a basic recursion to create multi-dimensional arrays based on the values of an inputed array.
The recursion works by checking for a value we shall call it "recursion" to start the loop and looks for another value we'll call it "stop_recursion" to end.
Basically taking this array
array('One', 'Two', 'recursion', 'Three', 'Four', 'Five', 'stop_recursion', 'Six', 'Seven')
And making this array
array('One', 'Two', array('Three', 'Four', 'Five'), 'Six', 'Seven')
The code I have for it so far is as follows
function testRecrusion($array, $child = false)
{
$return = array();
foreach ($array as $key => $value) {
if ($value == 'recursion') {
unset($array[$key]);
$new = testRecrusion($array, true);
$array = $new['array'];
$return[] = $new['return'];
} else {
if ($value == 'stop_recursion') {
unset($array[$key]);
if ($child) {
return array('return' => $return, 'array' => $array);
}
} else {
unset($array[$key]);
$return[] = $value;
}
}
}
return $return;
}
But the output from that is
Array
(
[0] => One
[1] => Two
[2] => Array
(
[0] => Three
[1] => Four
[2] => Five
)
[3] => Three
[4] => Four
[5] => Five
[6] => Six
[7] => Seven
)
I guess the real question is...will an array values continuously loop through the first values given from the initial call or once the new array is returned and set will it loop through that new array. I know the answer is basically right here saying that yes it will continue the old array value, but shouldn't this work vice-versa?
Any help will be appreciated :)
------------ edit -------------------
I might as well add that while I can perform this action using a much simpler method, this needs to be recursively checked since this will be ported to a string parser that could have a infinite number of child arrays.
When you return inside the recursion, you need to return both the inner array and the index from which to continue searching for elements so that you don't look at the same element twice. Try this instead:
function testRecursionImpl($array, $i)
{
$return = array();
for (; $i < sizeof($array); ++$i) {
if ($array[$i] == 'recursion') {
$new = testRecursionImpl($array, $i + 1);
$return[] = $new[0];
$i = $new[1];
} else if ($array[$i] == 'stop_recursion') {
return array($return, $i);
} else {
$return[] = $array[$i];
}
}
return array($return, $i);
}
function testRecursion($array)
{
$result = testRecursionImpl($array, 0);
return $result[0];
}
The problem you have in the code above is that you correctly detect when you should call this function recursively but once it finishes running and you append the results to output array you just pick next element (which is the first element that recursive call will get) and append it to output array. What you probably want to do is when you detect that you should run your function recursively you should skip all other characters until you find your stop word (stop_recursion). Obviously the problem will become harder if you allow multi-level recursion then you may need to even skip some stopwords because they could be from the different level call.
Still I don't know why you want such a feature. Maybe you would explain what are you trying to achieve. I'm pretty sure there's another, simpler way of doing it.
Rather than helping with your homework, I would suggest you start with getting rid of this line:
foreach ($array as $key => $value) {
You should just pass in your array, and check for being at the end of the array, since it can't really be infinite, to know when you are done.
Let me give it a try
function testRecursion($arr){
$return = array();
$recurlevel = 0;
foreach ($arr as $v) {
if($v == 'stop_recursion'){
$recurlevel--;
}
if($recurlevel == 0){
if(isset($current)){
$return[] = testRecursion($current);
unset($current);
}else{
if($v != 'recursion'){
$return[] = $v;
}
}
}else{
if(!isset($current)){
$current = array();
}
$current[] = $v;
}
if($v == 'recursion'){
$recurlevel++;
}
}
return $return;
}
Alright nicely done. This will help even if the recursion and stop_recursion are nested in another. See example:
code.php:
<pre><?php
function testRecursion($arr){
$return = array();
$recurlevel = 0;
foreach ($arr as $v) {
if($v == 'stop_recursion'){
$recurlevel--;
}
if($recurlevel == 0){
if(isset($current)){
$return[] = testRecursion($current);
unset($current);
}else{
if($v != 'recursion'){
$return[] = $v;
}
}
}else{
if(!isset($current)){
$current = array();
}
$current[] = $v;
}
if($v == 'recursion'){
$recurlevel++;
}
}
return $return;
}
$a = array('One', 'Two', 'recursion', 'Three', 'recursion', 'Four' , 'stop_recursion', 'Five', 'stop_recursion', 'Six', 'Seven');
var_dump(testRecursion($a));
?>
Browser output:
array(5) {
[0]=>
string(3) "One"
[1]=>
string(3) "Two"
[2]=>
array(3) {
[0]=>
string(5) "Three"
[1]=>
array(1) {
[0]=>
string(4) "Four"
}
[2]=>
string(4) "Five"
}
[3]=>
string(3) "Six"
[4]=>
string(5) "Seven"
}
Since your question for the recursive solution has already been answered ...might I offer a stack-based solution?
$x = array('a', 'b', 'recursion', 'cI', 'cII', 'cIII', 'recursion', 'cIV1', 'cIV2', 'cIV2', 'stop_recursion', 'stop_recursion', 'd', 'e');
$result = array();
$stack = array(&$result);
foreach($x as $e) {
if ( 'recursion'===$e ) {
array_unshift($stack, array());
$stack[1][] = &$stack[0];
}
else if ( 'stop_recursion'===$e ) {
array_shift($stack);
}
else {
$stack[0][] = $e;
}
}
var_dump($result);
prints
array(5) {
[0]=>
string(1) "a"
[1]=>
string(1) "b"
[2]=>
array(4) {
[0]=>
string(2) "cI"
[1]=>
string(3) "cII"
[2]=>
string(4) "cIII"
[3]=>
array(3) {
[0]=>
string(4) "cIV1"
[1]=>
string(4) "cIV2"
[2]=>
string(4) "cIV2"
}
}
[3]=>
string(3) "d"
[4]=>
string(5) "e"
}

Categories