Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 9 days ago.
Improve this question
$MainArr = array("S / White", "S / Red", "S / Black", "M / White", "M / Red", "M / Black", "L / White", "L / Red", "L / Black");
I have this array that should be similar words sorted accordingly
$arr = array("Red", "Black");
You can see that the output is coming according to its similar words
$outputarr = array("S / Red", "M / Red", "L / Red", "S / Black", "M / Black", "L / Black", "S / White", "M / White", "L / White");
What do I have to do about this?
<?php
$MainArr = array("S / White", "S / Red", "S / Black", "M / White", "M / Red", "M / Black", "L / White", "L / Red", "L / Black");
$arr = array("Red", "Black");
$sortArr = [];
foreach ($arr as $value) {
foreach ($MainArr as $main) {
if (strpos($main, $value) !== false) {
$sortArr[] = $main;
}
}
}
$difArr = array_udiff($MainArr, $sortArr, "strcasecmp");
$outputArr = array_merge($sortArr, $difArr);
echo "<pre>";
print_r($outputArr);
echo "</pre>";
exit;
?>
There is another way than that?
try this:
<?php
$MainArr = ["S / White", "S / Red", "S / Black", "M / White", "M / Red", "M / Black", "L / White", "L / Red", "L / Black"];
$arr = ["Red", "Black"];
$outputArr = [];
foreach ($arr as $color) {
$outputArr = array_merge($outputArr, array_filter($MainArr, function($item) use ($color) {
return strpos($item, $color) !== false;
}));
}
$outputArr = array_merge($outputArr, array_diff($MainArr, $outputArr));
echo "<pre>";
print_r($outputArr);
echo "</pre>";
?>
The final $outputArr is generated similarly to the OP solution but as a one-liner.However, the elements that contain the values in $arr could have been filtered without the need of the nested loop. Firstly, $MainArr items are filtered using the array_filter in a foreach loop.
It returns a new array with the elements for which the callback funtion returns true.
use keyword passes $color variable into anonymous callback function scope.
The strpos($item, $color) !== false; condition checks if the current color is found in item.
If $color was found in the $item, the filtered items are added to the $outputArr array.
Related
I have an array contain n number of elements can be 6 or 8, like that:
$langs = ["PHP", "JAVA", "Ruby", "C", "C++", "Perl"];
I would like to add one year evenly next to the elements
Desired output in case of 6 elements:
PHP - 2022
JAVA - 2022
Ruby - 2022
C - 2023
C++ - 2023
Perl - 2023
Desired output in case of 9 elements:
PHP - 2022
JAVA - 2022
Ruby - 2022
C - 2023
C++ - 2023
Perl - 2023
Python - 2024
Javascript - 2024
Mysql - 2024
My try :
$date = Carbon::now();
foreach($langs as $key => $lang){
if(count($langs) % $key == 0){
echo $lang .' - '. $date->addYear();
}
}
Bump the year every time $key is not zero and $key / 3 has no remainder.
Code: (Demo)
$langs = ["PHP", "JAVA", "Ruby", "C", "C++", "Perl", "Perl", "Python", "Javascript", "Mysql"];
$date = Carbon::now();
foreach ($langs as $key => $lang){
if ($key && $key % 3 === 0) {
$date->addYear();
}
echo $lang .' - '. $date->year . PHP_EOL;
}
To be perfectly honest, I don't see any benefit is calling a datetime wrapper for this very basic task. You can easily replace all usage of Carbon with PHP's native date() function. (Demo)
$langs = ["PHP", "JAVA", "Ruby", "C", "C++", "Perl", "Perl", "Python", "Javascript", "Mysql"];
$year = date('Y');
foreach ($langs as $key => $lang){
if ($key && $key % 3 === 0) {
++$year;
}
echo $lang .' - '. $year . PHP_EOL;
}
I'd use %3 as suggested by #mickmackusa but I would avoid incrementing the year of a date object as here you just need to get the year number and increment it (the month/day/hour/etc. is not an info you need to keep):
$langs = ["PHP", "JAVA", "Ruby", "C", "C++", "Perl", 'foo', 'bar', 'bam'];
$year = Carbon::now()->year;
foreach ($langs as $key => $lang){
if ($key && $key % 3 === 0) {
$year++;
}
echo $lang .' - '. $year . PHP_EOL;
}
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 6 years ago.
Improve this question
I have this in my php code:
$aNumbers = array(2,8,9,5.5,4,5.5,6,7,8,9,10,1,'NB');
From this I must determine the amount of values above 5.5 and the average of all numbers combined. Using only a For Loop, if/else construction and the count() function.
I have tried to solve this myself, but nowhere on the internet I can find sufficient information.
This should do it:
$aNumbers = array(2,8,9,5.5,4,5.5,6,7,8,9,10,1,'NB');
const HIGH_VALUE_CUTOFF = 5.5;
$uncleanArrayCount = count($aNumbers);
$cleanArray = array();
$highValueCount = 0;
$sum = 0;
for ($i = 0; $i < $uncleanArrayCount; $i++) {
if ($aNumbers[$i] > 0) { // catch only numbers
$sum += $aNumbers[$i];
$cleanArray[] = $aNumbers[$i]; // builds an array of numbers
}
if ($aNumbers[$i] > HIGH_VALUE_CUTOFF) {
$highValueCount++;
}
}
$average = $sum / count($cleanArray);
echo "Average: $average <br />";
echo "Numbers above " . HIGH_VALUE_CUTOFF . ": $highValueCount";
Next time, post what you've tried. 'Twas fun doing your homework for you!
Try something like this:
<?php
$sum = 0;
$amount = 0;
$aNumbers = array(2, 8, 9, 5.5, 4, 5.5, 6, 7, 8, 9, 10, 1, 'NB');
foreach ($aNumbers as $value){
if($value > 5){
$sum += $value;
$amount++;
}
}
echo "Sum : " . $sum . " - Average : ". ($sum / $amount);
?>
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 7 years ago.
Improve this question
First of all I need to find average of array, and then I need to find minimum difference between average of array and elements in that array and to display on which place is that element. This is the array:
myArray(4,-18,78,136,-52,14,19,-35,162,71,19,-5,-134,77,-78,-35,19);
You can try this:
<?php
$myArray = array(4,-18,78,136,-52,14,19,-35,162,71,19,-5,-134,77,-78,-35,19);
$averageArray = "";
//Average of the array
if(count($myArray) > 0) {
$averageArray = array_sum($myArray) / count($myArray);
}
$diff = array();
//Diff of average value and each value in a array named diff
if(isset($myArray)) {
foreach($myArray as $value) {
$diff[] = abs($averageArray - $value);
}
}
$key = array_search(min($diff),$diff);
echo "average = " . $averageArray .' - min value :'.min($diff).' - index:'.$key .' value: '.$myArray[$key]."\n";
The first step is to conceptualise an algorithm. What comes to mind is: find the average, find the absolute difference from each element to the average, and then find the minimum. The average can be calculated from the sum and the length.
$avg = array_sum($array) / count($array);
$diff = function ($x) use ($avg) { return abs($x - $avg); };
$answer = min(array_map($diff, $array));
To also get the element that is closest to the average, instead of mapping to just the difference we can keep the original element along for the ride. Then when we find the minimum we only compare the difference.
function minBy(callable $f, array $xs) {
$min = $xs[0];
foreach ($xs as $x) {
if ($f($x, $min) < 0) $min = $x;
}
return $min;
}
$avg = array_sum($array) / count($array);
$diff = function ($x) use ($avg) { return array($x, abs($x - $avg)); };
$byDiff = function ($x,$y) { return $x[1] - $y[1]; };
$answer = minBy($byDiff, array_map($diff, $array));
To find the index of the element in the array (note that this may not be unique), you can use array_search.
Crude but working:
<?php
$myArray = [4,-18,78,136,-52,14,19,-35,162,71,19,-5,-134,77,-78,-35,19];
// the average: sum/count
$average = round(array_sum($myArray) / count($myArray));
foreach ($myArray as $value) {
$diffs[] = abs($average - $value);
}
asort($diffs);
print_r($diffs);
$d = reset($diffs);
$p = array_search($d, $diffs);
echo sprintf("Average: %s, min diff: %s, diff pos: %s\n", $average, $d, $p);
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Closed 9 years ago.
Improve this question
So for example to get to a value of 237 given a denomination set of 1, 2, 5, 10, 20, 50 the optimal way to make up the value would be 4x50 + 1x20 + 1x10 + 1x5 + 1x2. But how to achieve that programatically in PHP?
You could do something like this :
$number = 237;
$values = array(1, 2, 5, 10, 20, 50);
arsort($values); // greater to lower sorting
$numberOf = array();
foreach ($values as $v) {
$numberOf[$v] = floor($number / $v);
$number -= $numberOf[$v] * $v;
}
var_dump($numberOf);
This will produce :
array(6) {
[50]=>
int(4)
[20]=>
int(1)
[10]=>
int(1)
[5]=>
int(1)
[2]=>
int(1)
[1]=>
int(0)
}
the demo
Edit : Denominations with finit amounts
If you don't have infinit denominations, you can try this :
$number = 237;
$values = array(1, 2, 5, 10, 20, 50);
$quantities = array(7, 1, 3, 5, 2, 3);
// sort by greater value to lower value
// but keeping the related quantities
array_multisort($values, SORT_DESC, $quantities);
$numberOf = array();
foreach ($values as $i => $v) {
$quantity = $quantities[$i]; // get the corresponding quantity
// if we have less than the required value, we put the max we can
$numberOf[$v] = floor($number / $v) > $quantity ? $quantity : floor($number / $v);
$number -= $numberOf[$v] * $v;
}
var_dump($numberOf);
In this example, you only have a quantity of 3 for 50. So you will have an output like :
array(6) {
[50]=>
int(3)
[20]=>
int(2)
[10]=>
float(4)
[5]=>
float(1)
[2]=>
float(1)
[1]=>
float(0)
}
3 * 50 + 2 * 20 + 4 * 10 + 5 * 1 + 2 * 1 + 1 * 0 = 237
Yippee !
The demo
See also array_multisort() to understand this key line :
array_multisort($values, SORT_DESC, $quantities);
And even better, a ready to go function :
function getDenominations($amount, $denominations, $quantities = null) {
if (is_array($quantities) && count($denominations) != count($quantities)) return false;
array_multisort($denominations, SORT_DESC, $quantities);
$numberOf = array();
foreach ($denominations as $i => $v) {
$quantity = $quantities[$i];
$numberOf[$v] = floor($amount/ $v) > $quantity ? $quantity : floor($amount / $v);
$amount -= $numberOf[$v] * $v;
}
return $amount == 0 ? $numberOf : false;
}
To use like this :
$result = getDenominations(
237,
array(1, 2, 5, 10, 20, 50),
array(7, 1, 3, 5, 0, 4)
);
var_dump($result);
Return values : array|bool
If no quantity is specified, it returns the denominations with infinite amount. If specified, with finite amount.
Returns "false" whether there's not enough quantities or if the sizes of the arrays are different.
I'm attempting to output a certain number of zeros depending on the number of digits. My code doesn't output what I want.
$x = '12345';
$y = preg_replace('/(\d+)/', str_pad('',(12-strlen("$1")),0), $x);
echo "y = $y";
# expected output: y = 0000000 (7 zeros)
# output: y = 0000000000 (10 zeros)
Like dev-null-dweller said in the comments you should use preg_replace_callback():
// This requires PHP 5.3+
$x = '12345';
$y = preg_replace_callback('/\d+/', function($m){
return(str_pad('', 12 - strlen($m[0]), 0));
}, $x);
echo "y = $y";
I did this which works:
<?php
$x = '12345';
$y = str_pad(preg_replace('/(\d+)/', "0", $x), 12 - strlen($x), "0", STR_PAD_LEFT);
echo "y = $y";
There is also this regular expression version too:
$y = str_pad(preg_replace('/\d/', "0", $x), 12 - strlen($x), "0", STR_PAD_LEFT);
There is also this, if you wan't the final output to look like: 0012345
$y = str_pad($x, 7, "0", STR_PAD_LEFT);