So I have a collection of integer values, which is built from a result of another function that can have different values every time. Consider the following in PHP:
$arr = [0,0,2,2,0,0,0,3,3];
Which i need to convert to:
$newArr = [null,0,2,2,0,null,0,3,3];
What i want to accomplish is: If a value is > 0, its neighbours should be 0, and the rest should be null.
What is the best strategy here?
Playing with operator precedence:
$zero = true;
$arr = [0,0,2,2,0,0,0,3,3];
$newArr = [];
foreach($arr as $k=>$v) {
if ($v) {
$newArr[] = $v;
$zero = false;
} else {
if ($zero and isset($arr[$k+1]) && !$arr[$k+1] || !isset($arr[$k+1]))
$newArr[] = null;
else
$newArr[] = 0;
$zero = true;
}
}
print_r($newArr);
Looping through the entire array, we evaluate each element for three conditions:
1.Element is zero.
2.Previous element is set, and it is equal to zero or null.
3.Next element is set, and it is equal to zero or null.
<?php
foreach($array as $key => $element)
{
if($element == 0 && ((isset($array[$key - 1]) && !$array[$key - 1]) || (isset($array[$key + 1]) && !$array[$key + 1])))
{
$array[$key] = null;
}
}
?>
I think it should work for you:
<?php
$arr = [0,0,2,2,0,0,0,3,3];
$new_array = $arr;
$array_count = count($arr);
for ($i=0; $i<$array_count; $i++) {
if ($i == 0 && $arr[$i+1] == 0) {
$new_array[$i] = null;
} elseif ($i == ($array_count-1) && $arr[$i-1] == 0) {
$new_array[$i] = null;
} elseif ($arr[$i-1] == 0 && $arr[$i+1] == 0) {
$new_array[$i] = null;
}
}
echo "<pre>";
print_r($new_array);
?>
We need to check for three conditions: is there, prev. is zero and next is zero.
You can combine first two conditions into the third one.
Broke it down for simplicity.
$array = [0,0,2,2,0,0,0,3,3];
$newArray = [];
foreach ($array as $key => $val) {
$previous = NULL;
$next = NULL;
if (isset($array[$key + 1])) {
$next = $array[$key + 1];
}
if ($key != 0) {
$previous = $array[$key - 1];
}
if ($val === 0 && $next == 0 && $previous == 0) {
$newArray[] = 'NULL';
} else {
$newArray[] = $val;
}
}
Another way to do this:
$arr = [0,0,2,2,0,0,0,3,3];
foreach($arr as $key => $value){
if($arr[$key] > 0 && isset($arr[$key - 1]) && $arr[$key - 1] == 0){
if(isset($arr[$key - 2]) && $arr[$key - 2] == 0){
$arr[$key - 2] = null;
}
}
if($arr[$key] > 0 && isset($arr[$key + 1]) && $arr[$key + 1] == 0){
if(isset($arr[$key + 2]) && $arr[$key + 2] == 0){
$arr[$key + 2] = null;
}
}
}
echo '<pre>';
print_r($arr);
echo '</pre>';
Here, i am looking for the positive value first then checking and if neighbor is 0 then set neighbor's neighbor to null.
<?php
$arr = [0,0,2,2,0,0,0,3,3];
$extra = [];
for($x=0; $x<count($arr); $x++){
if($arr[$x] == 0){
$tmp = isset($tmp)?$tmp:[];
$tmp[]=$x;
}else{
if(isset($tmp)){
$extra[] = $tmp;
unset($tmp);
}
}
}
foreach($extra as $subArr){
if(count($subArr) == 2){
$arr[$subArr[0]] = null;
$arr[$subArr[1]] = 0;
}else if(count($subArr) == 3){
$arr[$subArr[0]] = 0;
$arr[$subArr[1]] = null;
$arr[$subArr[2]] = 0;
}
}
var_dump($arr);
// YIELDS::
array (size=9)
0 => null
1 => int 0
2 => int 2
3 => int 2
4 => int 0
5 => null
6 => int 0
7 => int 3
8 => int 3
Related
There is a task. the function accepts the parameter 'odd' or 'even' - strings and array. And it returns the number of either odd or even elements in the array, depending on the parameter. Tell me where I was wrong?
function () {
$num = 'even';
$arr = [1,2,3,4,5,6,7,8,9];
in_array($num, $arr) {
if($num == 'even') {
return $arr % 2 == 0;
} else {
return $arr % 2 !== 0;
}
}
}
Here is your result. In your program, you are performing a modular operation on an entire array, which is not supported. You need to check each element of an array.
$result = [];
$num = 'even';
$arr = [1,2,3,4,5,6,7,8,9];
function _in_array($num, $arr) {
foreach($arr as $value){
if($num == 'even'){
if($value % 2 == 0){
$result[] = $value;
}
}else{
if($value % 2 != 0){
$result[] = $value;
}
}
}
return $result;
}
Let's say I have an array like that:
[12,3,4,5,8,9,11,20]
and a given number 7, then the predecessor/successor from the array would be 5/8 How do I find these numbers in an effective way?
At the moment I have the solution only for finding the successor via comparison.
Your need to iterate over the array and compare every number, than save the number, if it is more close to your needle, than the old one:
function precessorAndSuccessor(array $numbers, int $needle){
$pre = NULL;
$suc = NULL;
foreach($numbers as $number){
if($number < $needle){
if($pre === NULL || $pre < $number){
$pre = $number;
}
}elseif($number > $needle){
if($suc === NULL || $suc > $number){
$suc = $number;
}
}
}
return [
"predecessor" => $pre,
"successsor" => $suc
];
}
``
If you sort the array then just run through and check:
$num = 7;
$pre = $suc = false;
sort($array);
foreach($array as $v) {
if($v < $num) { $pre = $v; }
if($v > $num) { $suc = $v; break; }
}
i have array:
Array ( [0] => 1 [1] => 2 [2] => 3 [3] => 7 )
how to make condition in php when looping i can get output:
$datarange = 1-3,7;
i got logic like this:
if (value of array[0] + 1) = value of array[1] {
$datarange = value of array[0] - value of array[1];
}else{
$datarange = value of array[0] , value of array[1];
}
but i dont know how to Implement that to my looping
Here's a function that will make ranges when possible in an array of numbers.
<?php
function getRange($numbers) {
$lastNumber = null;
$currentRange = [];
$ranges = [];
foreach ($numbers as $number) {
if ($lastNumber === null) { // first iteration, add the number to current range
$currentRange[] = $number;
}
else {
if ($number - $lastNumber === 1) { // if difference with last number is 1, they're consecutive
$currentRange[] = $number;
}
else { // they're not consecutive, finish current range and start a new one
$ranges[] = $currentRange;
$currentRange = [$number];
}
}
$lastNumber = $number; // set the last number to compare with the next
}
$ranges[] = $currentRange; // add last range
$rangesString = []; //
foreach ($ranges as $range) {
$str = $range[0];
if (count($range) > 1) {
$str .= "-".$range[count($range) - 1];
}
$rangesString[] = $str;
}
return implode(", ", $rangesString);
}
echo getRange([1,2,3,7]); // result = 1-3, 7
echo getRange([1,2,6,9,10,12,15,17,18,19]); // result = 1-2, 6, 9-10, 12, 15, 17-19
Try this. I have change your logic and apply it in loop. for range:
$arr = array(1,2,3,7);
$last_val = "";
$first_val = "";
$add_val = true;
foreach ($arr as $key => $value) {
if($first_val == "")
$first_val = $value;
if(isset($arr[$key+1]))
{
if($value+1 == $arr[$key+1])
{
$last_val = $arr[$key+1];
$add_val = false;
}
else
$add_val = true;
}
else
$add_val = true;
if($add_val)
{
if($last_val != "")
$datarange[] = $first_val."-".$last_val;
else
$datarange[] = $first_val;
$first_val = "";
$last_val = "";
}
}
echo implode(",", $datarange);
DEMO
i have a 1D arrayA and a 2D arrayB.
arrayA[0] = 'D'
arrayA[1] = 'U'
arrayA[3] = 'R'
arrayA[4] = 'B'
arrayA[5] = 'S'
arrayA[6] = 'H'
arrayB[0][0] = 'D' arrayB[0][1] = 2
arrayB[1][0] = 'B' arrayB[1][1] = 1
arrayB[2][0] = 'R' arrayB[2][1] = 1
arrayB[3][0] = 'U' arrayB[3][1] = 1
arrayB[4][0] = 'H' arrayB[4][1] = 0
arrayB[5][0] = 'S' arrayB[5][1] = 0
arrayB[x][y] is sorted - based on y.
I have to create a new array using the letters, first giving priority on y from arrayB[x][y].
But there are some same values in y like, 1 three times and 0 two times.
In this situation similar values will be sorted according to arrayA.
and the new array will sort like :
D, U, R, B, S, H
How can i do it efficiently ?
thanks in advance
In the code below, $string corresponds to arrayB[x][0], $weight corresponds to arrayB[x][1] and $order corresponds to arrayA:
<?php
$string = str_split('DBRUHS');
$weight = str_split('211100');
$result = '';
function my_sort($a, $b)
{
$order = str_split('DURBSH');
$a = array_search($a, $order);
$b = array_search($b, $order);
if ($a === $b) return 0;
if ($a === FALSE) return -1;
if ($b === FALSE) return 1;
if ($a == $b) return 0;
return ($a < $b) ? -1 : 1;
}
arsort($weight);
$current_priority = -1;
$substring = array();
$max = count($weight);
$count = 1;
foreach ($weight as $position => $priority)
{
if ($count++ == $max)
{
$substring[] .= $string[$position];
$priority = $current_priority + 1;
}
if ($current_priority != $priority)
{
if (!empty($substring))
{
usort($substring, 'my_sort');
$result .= implode('', $substring);
}
$current_priority = $priority;
$substring = array($string[$position]);
}
else
{
$substring[] = $string[$position];
}
}
print_r(str_split($result));
?>
I tried this and it worked fine. a1 is the 1d array, a2 is the 2d.
EDIT: This works now.
function sortArr($a1, $a2) {
$t1 = array();
foreach ($a1 as $v) {
$t2 = array();
foreach ($a2 as $i=>$k) {
if ($k[0] == $v) {
$t2[0] = $k[0];
$t2[1] = $k[1];
$t1[$i] = $t2;
break;
}
}
}
return $t1;
}
I have an array with about 360 keys:
$threadColours['Apricot'] = array(250,180,160,3341,328,826,194,3332,0);
$threadColours['Apricot, Light'] = array(255,230,225,3824,8,833,2605,-1,1);
$threadColours['Apricot, Medium'] = array(255,135,105,3340,329,827,193,-1,2);
I am retrieving a pixel rgb values that came from this array. So I need to get the key where, for example, $threadColours[???][0]=250, [1]=180, [2]=160. I know you can search for a single key but I cannot figure out how to match multiple values. Just to be clear, I have the rgb values I just want to know how to get the key that has all three values in [0],[1],[2] respectively.
Thank you much,
Todd
function getColourKey($colours, $r, $g, $b) {
foreach ($colours as $key => $value)
if ($value[0] == $r && $value[1] == $g && $value[2] == $b)
return $key;
return NULL;
}
You can use code like this:
$threadColours['Apricot'] = array(250,180,160,3341,328,826,194,3332,0);
$threadColours['Apricot, Light'] = array(255,230,225,3824,8,833,2605,-1,1);
$threadColours['Apricot, Medium'] = array(255,135,105,3340,329,827,193,-1,2);
$needle=array(2605,-1,1); // this is your r,g,b
$startIndex = -1;
$rootElem = "";
foreach ($threadColours as $key => $arr) {
for ($i=0; $i < count($arr); $i+=3) {
if ( $arr[$i] == $needle[0] &&
$arr[$i+1] == $needle[1] &&
$arr[$i+2] == $needle[2]
) {
$rootElem = $key;
$startIndex = $i;
break;
}
}
}
printf("rootElem=[%s], startIndex=[%s]\n", $rootElem, $startIndex);
OUTPUT:
rootElem=[Apricot, Light], startIndex=[6]
$search = array(250, 180, 160);
$color = null;
foreach ($threadColours as $key => $val) {
if (array_slice($val, 0, 3) == $search) {
$color = $key;
break;
};
}