I have a $test array which contains strings. I also have two functions, replaceOverlap that merges two overlapped strings and findNested that finds if one of the two strings is a substring from the other. The code is in PHP
What I would like to do is to iterate over the $test array and take each element ($epitope) and compare it with the rest of the $epitopes in the array one at a time, as there are some more rules in the algorithm. The issue is that if I only want to print the biggest overlapped-nested string found across the rest of the $test array, and then delete from the array those string that have been merged. This is the code I have so far. Any help will be very appreciated.
$test=array(AVNIVGYSNAQGVDY,DIKYTWNVPKI,DIKYTWNVPKIA,DIKYTWNVPKIAPKSEN,GCHGSEPCIIHRGK,IDGLEVDVPGIDPNAC,IGIKDLRAFQHYDGRTI,IIHRGKPFQLEAV,IKYTWNVPKIAPKSEN,KPFQLEAVFEANQNT,LRQMRTVTPIRMQGG,NFLESLKYVEANKGAIN,PCIIHRGKPFQLEAV,PLVKGQQYDIKYTWNVP,QQYDIKYTWNVPKI,QQYDIKYTWNVPKIA,QQYDIKYTWNVPKIAP,QQYDIKYTWNVPKIAPK,QQYDIKYTWNVPKIAPKS,QQYDIKYTWNVPKIAPKSE,QQYDIKYTWNVPKIAPKSEN,QYDIKYTWNVPK,QYDIKYTWNVPKI,QYDIKYTWNVPKIAPKS,QYDIKYTWNVPKIAPKSEN,RFGISNYCQIYPPNV,SAYLAHRNQSLDLAEQELVDCAS,TAIAVIIGIKDLRAFQH,TWNVPKIAPKSENVVVT,YAYVAREQSCR,YDIKYTWNVPK,YDIKYTWNVPKI,YDIKYTWNVPKIA,YDIKYTWNVPKIAPKSEN);
$i=0;
foreach ($test as $epitope){
$str1=$epitope;
for ($j = $i; $j < count($test); ++$j) {
$str2=$test[$j];
$value1 = replaceOverlap($str1,$str2);
$value2 = replaceOverlap($str2,$str1);
$value3 = findNested($str1,$str2);
if (replaceOverlap($str1,$str2)!=false){
array_splice($test[$j]);
print $value1;echo"</br>";
}
elseif (replaceOverlap($str2,$str1)!=false){
array_splice($test[$j]);
print $value2;echo"</br>";
}
elseif (findNested($str1,$str2)!=false){
array_splice($test[$j]);
print $value3;echo"</br>";
}
}
$i=$i+1;
}
Related
I have an array $scripts_stack = []; that holds arrays:
$array_item = array('script' => $file_parts, 'handle' => $file_name, 'src' => $url);
array_push($scripts_stack, $array_item);
<?php
for ($i = 0; $i < sizeof($scripts_stack); $i++) {
$child_array = $scripts_stack[$i];
if (is_array($child_array)) {
// Do things with $child_array,
// then remove the child array from $scripts_stack when done with (BELOW)
unset($scripts_stack[$i]);
}
}
echo "Array Size : " . (sizeof($scripts_stack)); // AT THE END
However, my attemts only remove half the elements. No matter what I try, it's only half the items that get removed. sizeof($scripts_stack) is always half the size of what it was at the start.
I'm expecting that it would be empty // AT THE END
Why is it that I only get half the elements in the array removed?
Thank you all in advance.
As mentioned in other answers, $i increments but the sizeof() the array shrinks. foreach() is probably the most flexible looping for arrays as it exposes the actual key (instead of hoping it starts at 0 and increments by 1) and the value:
foreach ($scripts_stack as $key => $child_array) {
if (is_array($child_array)) {
// Do things with $child_array,
// then remove the child array from $scripts_stack when done with (BELOW)
unset($scripts_stack[$key]);
}
}
Just FYI, the way you're doing it with for almost works. You just need to establish the count before the loop definition, rather than recounting in the continuation condition.
$count = sizeof($scripts_stack);
for ($i = 0; $i < $count; $i++) { // ...
Still, I think it would be better to just use a different type of loop as shown in the other answers. I'd personally go for foreach since it should always iterate every element even if some indexes aren't present. (With the way you're building the array, it looks like the indexes should always be sequential, though.)
Another possibility is to shift elements off of the array rather than explicitly unsetting them.
while ($child_array = array_shift($scripts_stack)) {
// Do things with $child_array,
}
This will definitely remove every element from the array, though. It looks like $child_array should always be an array, so the is_array($child_array) may not be necessary, but if there's more to it that we're not seeing here, and there are some non-array elements that you need to keep, then this won't work.
You advanced $i while the array is getting shrinked, but in the same time you jump over items in your array.
The first loop is where $i == 0, and then when you removed item 0 in your array, the item that was in the second place has moved to the first place, and your $i == (so you will not remove the item in the current first place, and so on.
What you can do is use while instead of for loop:
<?php
$i = 0;
while ($i < sizeof($scripts_stack)) {
$child_array = $scripts_stack[$i];
if (is_array($child_array)) {
// Do things with $child_array,
// then remove the child array from $scripts_stack when done with (BELOW)
unset($scripts_stack[$i]);
} else {
$i++;
}
}
echo "Array Size : " . (sizeof($scripts_stack)); // AT THE END
May be you can use this script.It's not tested.
foreach($array as $key => $value ) {
unset($array[$key]);
echo $value." element is deleted from your array</br>";
}
I hope , it will help you.
The problem root is in comparing $i with sizeof($scripts_stack). Every step further sizeof($scripts_stack) becomes lower (it calculates at every step) and $i becomes higher.
The workaround may look like this:
<?php
$scripts_stack = [];
$array_item = array('script' => 1, 'handle' => 2, 'src' => 3);
array_push($scripts_stack, $array_item);
array_push($scripts_stack, $array_item);
array_push($scripts_stack, $array_item);
array_push($scripts_stack, $array_item);
array_push($scripts_stack, $array_item);
while (sizeof($scripts_stack) > 0) {
$child_array = array_shift($scripts_stack);
if (is_array($child_array)) {
// Do things with $child_array,
// then remove the child array from $scripts_stack when done with (BELOW)
}
}
echo "Array Size : " . (sizeof($scripts_stack)); // AT THE END
https://3v4l.org/N2p3v
I am trying to learn php, and I am playing around with while loops. I was wondering how to print out a specific number in an array in php. Fx:
$a = [1,3,5,7,9,11,13];
$s = 3;
while($a == 3) {
echo $s.' is in the row';
$a++;
}
In this example I would like to run through the $a and see if 3 exist there. If it does it has to echo '3 is in the row' I tried to make a while loop, but it is not correct. Can anyone see what I am doing wrong? Just to say it, I think it is very wrong, but I don't know how to solve it, if I have to use the while loop?
Best Regards
Mads
Your while condition reads: "While the value of $a equals 3", but $a is an array, so its value can't ever be 3. The loop will never be executed. In PHP, we would write:
if (in_array($s, $a))
echo $s, ' was found in the array';
Or, if you insist on writing loops:
foreach ($a as $key => $value)
{
if ($value == $s)
{
echo $s, ' was found at offset ', $key;
break;//end terminate loop
}
}
Of course, you could also write:
for ($i=0, $j=count($a);$i<$j;++$j)
{
if ($a[$i] == $s)
{//you could move this condition to the loop itself, even
echo $s, ' found in array at offset ', $i;
break;
}
}
You can, if you want use a while loop, too, but that wouldn't be the best choice for your particular case. Just read through the manual on php.net. There are many, many array_* functions available, and there are many ways to iterate over your data.
Another worry is your using the array name as a sort-of C-style pointer: $a++; in C, an pointer can be incremented to set it to point to the next value in an array (if the new memory address is valid, and the pointer is valid, and all of the other things you have to worry about in C). PHP does not work this way. An array isn't really an array: it's a hash map. incrementing an array, therefore, is pointless and most likely to be a bug. The for loop is the closest you can get to traversing an array using the ++ operator.
You're looking for in_array. This checks if a value exists in an array, in the form of:
in_array ( mixed $needle , array $haystack )
So, in your case, you'd want to do:
$a = [1,3,5,7,9,11,13];
$s = 3;
if (in_array($s, $a)) {
echo $s.' is in the row';
}
foreach($a as $b) {
if($b == 3)
echo $b.' is in the row';
}
Modify slightly your code changing while condition:
$a = array(1,3,5,7,9,11,13);
$s = 3;
$counter = 0;
while($counter < count($a)) {
if ( $a[$counter] == $s )
echo $s.' is in the row';
$counter++;
}
Added counter to iterate through while loop until end of array.
count() method returns number of items in array.
This solution prints all occurences of your number.
To have better code, change names of variables:
$numbers = array(1,3,5,7,9,11,13);
$target = 3;
$counter = 0;
while($counter < count($numbers)) {
if ( $numbers[$counter] == $target )
echo $target.' is in the row';
$counter++;
}
There are two ways to do it,
First, you can loop through all items in the array using a foreach() loop.
That way, you can go through them all and if you have multiple conditions, it makes your code a bit more readable.
And example of that loop is like this:
foreach($array as $array_item) {
if($array_item === 3) {
echo "3 is in the array";
}
}
The alternative is to use a built in function to find if something is in the array. THis is probably much faster, though I haven't benchmarked the difference.
if(in_array(3, $array)) {
echo "3 is in the array";
}
you can use
array_search ,in_array , and forearch or for loops to itertate through the array.
For learning purposes
$a = [1,3,5,7,9,11,13];
$s = 3;
for($i=0;$i<count($a);$i++)
{
if($a[$i]==$s){
echo $s.' is in the row';
}
}
of course in real life
if (in_array(3, $a)) {
// Do something
}
would be better;
<?php
$a = [1,3,5,7,9,11,13];
$s = 3;
for($a=0;$a < 20; $a++)
{
while($a == 3) {
echo $s.' is in the row';
//$a++;
}
}
?>
I'm having some trouble figuring out how to make my function return a concatenated list of converted strings. The goal is to process 2 parallel arrays and use the value in one array ('U' or 'L') to cause the value (words) in the parallel array to convert to all upper or lower case, using a loop.
I want to return a concatenated list of the converted results.
I want no parameters to be used.
Right now it's just returning the first word, I'm not sure how to make it return the whole array of words. Any help is appreciated!
<?php
$case[0]='U'; // I just made these arrays up for the purpose of testing
$case[1]='L'; // the $case array values will be either U or L
$case[2]='U';
$case[3]='L';
$strings[0]='tHese'; // the $strings array values are words of varying case
$strings[1]='aRe';
$strings[2]='rAndoM';
$strings[3]='wOrDs';
function changeCase () {
global $case;
global $strings;
$total = "";
for ($i = 0; $i < sizeof($case); $i++) {
if ($case[$i] == "U") return strtoupper($strings[$i]);
elseif ($case[$i] == "L") return strtolower($strings[$i]);
$total = $total + $strings[$i]; //the returned value should look like THESEareRANDOMwords
}
return $total;
};
echo changeCase ();
?>
<?php
function changeCase ($case, $strings) {
$total = '';
foreach($case as $i=>$type)
$total .= ($type=='U') ? strtoupper($strings[$i]) : strtolower($strings[$i]);
return $total;
}
$case[0]='U'; // I just made these arrays up for the purpose of testing
$case[1]='L'; // the $case array values will be either U or L
$case[2]='U';
$case[3]='L';
$strings[0]='tHese'; // the $strings array values are words of varying case
$strings[1]='aRe';
$strings[2]='rAndoM';
$strings[3]='wOrDs';
echo changeCase($case, $strings);
You are using return in the loop, which will get you out of the function. You never reach the $total=... part.
array_map() is perfect for this.
$case[0]='U';
$case[1]='L';
$case[2]='U';
$case[3]='L';
$strings[0]='tHese';
$strings[1]='aRe';
$strings[2]='rAndoM';
$strings[3]='wOrDs';
// Set up an anonymous function to run on $case, and pass in $strings
$funct = function($value, $key) use ($strings) {
if($value == "U")
return strtoupper($strings[$key]);
else
return strtolower($strings[$key]);
};
// Pass in our keys as an additional parameter, this is not usual
// but in this case we need the keys to access the $strings array
$results = array_map($funct, $case, array_keys($case));
var_dump(implode("", $results));
I have a list of letters. I compare this list of letters against an array of the alphabet and get the difference. Then they're put together into one array so I can output it as one list.
//start the array
$alphabet = array();
//the letters I'm using
$letters = array('A','B','C','D','E','F','G','H','I','J','L','M','N','O','P','R','S','T','V');
//place into true array
foreach($letters as $l)
$alphabet['true'][] = $l;
//alphabet array, place into false array
foreach (range('A','Z') as $char)
$alphabet['false'][] = $char;
//the not used array by getting the difference of true and false arrays
$alphabet['actual'] = array_diff($alphabet['false'], $alphabet['true']);
//merge the arrays into one array
$new = array_merge($alphabet['true'],$alphabet['actual']);
//sort them naturally
natsort($new);
//list the results
echo "All together now: <pre>"; print_r($new); echo "</pre>";
Is there a way to style each of the different arrays key-values before placing them into the big array? Something along the lines of the not used letters are a different color? Or am I going about this the wrong way? Thank you for any insight.
If it where me I would do something like this.
//start the array
$alphabet = array();
//the letters I'm using
$used = array('A','B','C','D','E','F','G','H','I','J','L','M','N','O','P','R','S','T','V');
$alphabet = range('A','Z');
echo "<ul>";
foreach($alphabet as $letter){
if (in_array($letter, $used)){
echo "<li class='used'>".$letter."</li>";
} else {
echo "<li class='unused'>".$letter."</li>";
}
}
echo "</ul>";
and make a couple of css rules
li.used { color:green; }
li.unused { color:red; }
This question already has answers here:
Removing a value from a PHP Array
(3 answers)
Closed 8 years ago.
I have an array that looks like this
$hours_worked = array('23',0,'24',0)
What want to do is to loop through the array and remove the element that contains 0
What I have so far is:
for($i = 0; $i < count($hours_worked); $i++)
{
if($hours_worked[$i] === 0 )
{
unset($hours_worked[$i]);
}
}
However the result I get is $hours_worked = array(23,24,0). I.e. it does not remove the final element from the array. Any ideas?
The problem with this code is that you are calculating count($hours_worked) on each iteration; once you remove an item the count will decrease, which means that for each item removed the loop will terminate before seeing one item at the end of the array. So an immediate way to fix it would be to pull the count out of the loop:
$count = count($hours_worked);
for($i = 0; $i < $count; $i++) {
// ...
}
That said, the code can be further improved. For one you should always use foreach instead of for -- this makes the code work on all arrays instead of just numerically indexed ones, and is also immune to counting problems:
foreach ($hours_worked as $key => $value) {
if ($value === 0) unset($hours_worked[$key]);
}
You might also want to use array_diff for this kind of work because it's an easy one-liner:
$hours_worked = array('23',0,'24',0);
$hours_worked = array_diff($hours_worked, array(0)); // removes the zeroes
If you choose to do this, be aware of how array_diff compares items:
Two elements are considered equal if and only if (string) $elem1 ===
(string) $elem2. In words: when the string representation is the
same.
Try foreach loops instead
$new_array = array();
foreach($hours_worked as $hour) {
if($hour != '0') {
$new_array[] = $hour;
}
}
// $new_array should contain array(23, 24)