Initializing array shared values at once - php

Maybe this isn't possible, I've never seen it myself, but thought I'd ask. If this is my array,
$myarr = array(
'red' => 7,
'green' => 7,
'blue' => 18,
'cyan' => 14,
'pink' => 18
'brown' => 18
);
is there a way while initializing the array to set similar values at once? like
'red' && 'green' =>7,
'blue' && 'pink' && 'brown' => 18,
'cyan' =>14
of course I'm not expecting this syntax to work but is there something that gets me the same idea?

PHP Manual does not provide description of any way to do that. BTW, you may initialize values in the following way:
$myarr['red'] = $myarr['green'] = 7;
$myarr['blue'] = $myarr['pink'] = $myarr['brown'] = 18;
$myarr['cyan'] = 14;

It isn't possible and, honestly, I fail to see a situation it could be useful if the repeated values are in the same array.
Would you like to provide an example, in order for me to get it?
A fun aside:
$bibi = array (
'foo' == 'bar' => 2,
);
$bubu = array (
'foo' && 'bar' => 2,
);
Both this syntaxes actually evaluate the expressions on the left. As in, in 2 is assigned to $bibi[0] and $bubu[1].

Related

PHP Checkif two arrays have the same keys and same count of keys [duplicate]

This question already has answers here:
PHP - Check if two arrays are equal
(19 answers)
Check if two arrays have the same values (regardless of value order) [duplicate]
(13 answers)
How to check if PHP associative arrays are equal, ignoring key ordering?
(1 answer)
Closed 4 years ago.
I'm trying to match 2 arrays that look like below.
$system = array('blue' => 1, 'red' => 2, 'green' => 3, 'purple' => 4);
$public = array('blue' => 1, 'red' => 2, 'green' => 3, 'purple' => 4);
My problem is, I need the array keys of both arrays to be the same value and same count.
Which means:
// passes - both arrays have the same key values and same counts of each key
$system = array('blue' => 1, 'red' => 2, 'green' => 3, 'purple' => 4);
$public = array('blue' => 1, 'red' => 2, 'green' => 3, 'purple' => 4);
// fails - $public does not have 'blue' => 1
$system = array('blue' => 1, 'red' => 2, 'green' => 3, 'purple' => 4);
$public = array('red' => 2, 'green' => 3, 'purple' => 4);
// should fail - $public has 2 'blue' => 1
$system = array('blue' => 1, 'red' => 2, 'green' => 3, 'purple' => 4);
$public = array('blue' => 1, 'blue' => 1, 'red' => 2, 'green' => 3, 'purple' => 4);
I've tried using array_diff_keys, array_diff and other php functions, but none can catch extra keys with the same value (i.e. if 'blue' => 1, is repeated it still passes)
What's a good way to solve this?
When you write two values with same key in PHP, the second one will overwrite the value from the first (and this is not an error). Below is what I did on the PHP interactive CLI (run it with php -a):
php > $x = ["x" => 1, "x" => 2, "y" => 2];
php > var_dump($x);
array(2) {
["x"]=>
int(2)
["y"]=>
int(2)
}
So array_diff seems to be working correctly. You are just expecting PHP to behave in a different way than it actually does!

Laravel - Access a value from DB::table()->insert

I'm building an Insert query using Faker and I wonder whether it is possible to use a value to-be-inserted in another value.
Here is an example, not accurate for my situation but explains well:
DB::table('debts')->insert([
'name' => $faker->company,
'debt' => $faker->randomFloat($nbMaxDecimals = 2, $min = 20000, $max = 10000000),
'debt_paid' => 'debt' / rand ( 2 , 8 ),
'notes' => $faker->paragraph($nbSentences = 3, $variableNbSentences = true),
]);
As you can see, in the row of debt_paid I want to access the value of 'debt' that was randomly defined a row above. This is because debt_paid needs to be logical and without the value of debt it might be non-sense.
I know that defining 'debt' as a variable before the insert would solve it, but I wonder whether there's a more elegant solution.
So do that outside the insert
$dbt = $faker->randomFloat($nbMaxDecimals = 2, $min = 20000, $max = 10000000);
DB::table('debts')->insert([
'name' => $faker->company,
'debt' => $dbt,
'debt_paid' => $dbt / rand ( 2 , 8 ),
'notes' => $faker->paragraph($nbSentences = 3, $variableNbSentences = true),
]);

Avoid multiple if statements in PHP (use array or some other option)

I am creating a conversion table using PHP and I have to check the user's input against A LOT of scenarios and I started by using if statements but this doesn't seem to be efficient whatsoever and I was hoping for an easier way to go through all the scenarios.
I looked into ternary and switch options but those don't seem to do what I need it to do and I also considered array's (the option I think I need to use)
What I'm trying to do:
The user enters in a grade level and scores for a category. Based on the sum of those scores and the grade level, I need to compare them to get two other scores
Example code:
if ($grade == 1 && $sumScore <= 5)
{
$textscore = 'Beginning';
}
if ($grade ==1 && ($sumScore>5 && $sumScore <=8))
{
$textScore = 'Intermediate';
}
etc....
There are 13 grades (K-12) and 4 categories I need to go through all with their own "raw scores" to consider to get these other scores. How can I avoid using a ton of If/Else if statements?
Thanks!!
You could use a two-dimensional array that's 13x4. Then you can use a nested for loop to go through each possibility and just have one statement that gets run a bunch of times because of the for loops.
For example, the array might look like this:
$textscores = array (
1 => array(5 => 'Beginning', 8 => 'Intermediate', ...),
...
3 => array(5 => 'Intermediate', ...),
...
);
The nested for loop might look like this:
foreach($textscores as $grade => $scores) {
foreach($scores as $sumScore => $textScore) {
if($userGrade == $grade && $userSumScore <= $sumScore) {
$userTextScore = $textScore;
break 2;
}
}
}
I haven't tested this (sorry), but I think something like this
function getTextScore($grade, $sum) {
$rules = array( array("grade" => 1, "minSum" => null, "maxSum" => 5, "textScore" => "Beginning"),
array("grade" => 1, "minSum" => 6, "maxSum" => 8, "textScore" => "Intermediate" ),
/* ... */
);
for ($ruleIdx=0; $ruleIdx<count($rules); $ruleIdx++) {
$currentRule = $rules[$ruleIdx];
if (($currentRule['grade'] == $grade) &&
((is_null($currentRule['minSum'])) || ($currentRule['minSum'] <= $sum)) &&
((is_null($currentRule['maxSum'])) || ($currentRule['maxSum'] >= $sum))) {
return $currentRule['textScore'];
}
}
// got to the end without finding a match - need to decide what to do
}
The rules have optional min and max values. It will stop as soon as it finds a match, so the order is important. You will need to decide if no rules are matched. You should be able to just drop extra rules in or change the existing ones without changing the logic.
From your example I would suggest the following
Multidimensional array, but a bit different from the way you construct the array
// Grade => [Text => [Min,Max]]
$textScores = [
1 => [
'Beginning' => [0, 5],
'Intermediate' => [5, 8],
'Master' => [8, 10]
],
2 => [
'Beginning' => [0, 7],
'Intermediate' => [7, 8],
'Master' => [8, 10]
],
3 => [
'Beginning' => [0, 3],
'Intermediate' => [3, 6],
'Master' => [6, 10]
]
];
// Random input to test
$grade = rand(1, 3);
$sumScore = rand(0, 10);
foreach ($textScores[$grade] as $Text => $MinMax) {
if ($MinMax[0] <= $sumScore && $MinMax[1] >= $sumScore) {
$textScore = $Grade;
break;
}
}

PHP multidimensional array counter

Im trying to make a multidimensional array with two columns. Name and Counter. I can do a single array with all the names. But I dont know how to make it multidimensional and be able to still update the counters. Code i got so far is
if (!in_array($prodname, $da)){
array_push($da, $prodname);
}
and then I can dump it back out with a foreach. How do I make it two dimensional? How can I say alright this exists update the old value? etc.
If you only need name and counter then you should just be able to use a normal array:
$nameCountArray = array();
foreach($names as $name){
if(!array_key_exists($name,$nameCountArray)){
$nameCountArray[$name] = 1;
}else{
$nameCountArray[$name] = $nameCountArray[$name] + 1;
}
}
If you do need multidimensional arrays these are just arrays of arrays and can be accessed as such. A good example of this is using a 2d array to store locations (say on a 3 by 3 grid):
$twoDArray = array(
0 => array(0 => 1,
1 => 4,
2 => 7),
1 => array(0 => 2,
1 => 5,
2 => 8),
2 => array(0 => 3,
1 => 6,
2 => 9)
);
//Grab the item at 1,2
$item = $twoDArray[1][2];//Will give '8'
Supposing you want $da to look like this:
Array(
"name1" => array("score1" => 80, "score2" => 100),
"name2" => array("score1" => 50, "score2" => 60),
"name3" => array("score1" => 90, "score2" => 80),
...
)
Then all you need to do is something like:
function setScore($prodName, $scoreName, $score)
{
global $da;
if (!array_key_exists($prodName, $da)) {
$da[$prodName] = array();
}
$da[$prodName][$scoreName] = $score;
}
setScore("name1", "score1", 80);
setScore("name1", "score2", 100);
setScore("name2", "score1", 50);
...
Unless I'm misunderstanding your question, which is very possible.

get integer / float from string in PHP

I ran into an issue with a data feed I need to import where for some reason the feed producer has decided to provide data that should clearly be either INT or FLOAT as strings-- like this:
$CASES_SOLD = "THREE";
$CASES_STOCKED = "FOUR";
Is there a way in PHP to interpret the text string as the actual integer?
EDIT: I should be more clear-- I need to have the $cases_sold etc. as an integer-- so I can then manipulate them as digits, store in database as INT, etc.
Use an associative array, for example:
$map = array("ONE" => 1, "TWO" => 2, "THREE" => 3, "FOUR" => 4);
$CASES_SOLD = $map["THREE"]; // 3
If you are only interested by "converting" one to nine, you may use the following code:
$convert = array('one' => 1,
'two' => 2,
'three' => 3,
'four' => 4,
'five' => 5,
'six' => 6,
'seven' => 7,
'eight' => 8,
'nine' => 9
);
echo $convert[strtolower($CASES_SOLD)]; // will display 3
If you only need the base 10 numerals, just make a map
$numberMap = array(
'ONE' => 1
, 'TWO' => 2
, 'THREE' => 3
// etc..
);
$number = $numberMap[$CASES_SOLD];
// $number == 3'
If you need something more complex, like interpreting Four Thousand Two Hundred Fifty Eight into 4258 then you'll need to roll up your sleeves and look at this related question.
Impress your fellow programmers by handling this in a totally obtuse way:
<?php
$text = 'four';
if(ereg("[[.$text.]]", "0123456789", $m)) {
$value = (int) $m[0];
echo $value;
}
?>
You need a list of numbers in english and then replace to string, but, you should play with 'thousand' and 'million' clause where must check if after string 'thousend-three' and remove integer from string.
You should play with this function and try change if-else and add some functionality for good conversion:
I'm writing now a simple code for basic, but you know others what should change, play!
Look at million, thousand and string AND, it should be change if no in string like '1345'. Than replace with str_replace each of them separaterly and join them to integer.
function conv($string)
{
$conv = array(
'ONE' => 1,
'TWO' => 2,
'THREE' => 3,
'FOUR' => 4,
'FIVE' => 5,
'SIX' => 6,
'SEVEN' => 7,
'EIGHT' => 8,
'NINE' => 9,
'TEN' => 10,
'ELEVEN' => 11,
'TWELVE' => 12,
'THIRTEEN' => 13,
'FOURTEEN' => 14,
'FIFTEEN' => 15,
'SIXTEEN' => 16,
'SEVENTEEN' => 17,
'EIGHTEEN' => 18,
'NINETEEN' => 19,
'TWENTY' => 20,
'THIRTY' => 30,
'FORTY' => 40,
'FIFTY' => 50,
'SIXTY' => 60,
'SEVENTY' => 70,
'EIGTHY' => 80,
'NINETY' => 90,
'HUNDRED' => 00,
'AND' => '',
'THOUSAND' => 000
'MILLION' => 000000,
);
if (stristr('-', $string))
{
$val = explode('-', $string);
#hardcode some programming logic for checkers if thousands, should if trim zero or not, check if another values
foreach ($conv as $conv_k => $conv_v)
{
$string[] = str_replace($conv_k, $conv_v, $string);
}
return join($string);
}
else
{
foreach ($conv as $conv_k => $conv_v)
{
$string[] = str_replace($conv_k, $conv_v, $string);
}
return join($string);
}
}
Basically what you want is to write a parser for the formal grammar that represents written numbers (up to some finite upper bound). Depending on how high you need to go, the parser could be as trivial as
$numbers = ('zero', 'one', 'two', 'three');
$input = 'TWO';
$result = array_search(strtolower($input), $numbers);
...or as involved as a full-blown parser generated by a tool as ANTLR. Since you probably only need to process relatively small numbers, the most practical solution might be to manually hand-code a small parser. You can take a look here for the ready-made grammar and implement it in PHP.
This is similar to Converting words to numbers in PHP
PHP doesn't have built in conversion functionality. You'd have to build your own logic based on switch statements or otherwise.
Or use an existing library like:
http://www.phpclasses.org/package/7082-PHP-Convert-a-string-of-English-words-to-numbers.html

Categories