use of for loop counter in if condition php - php

Below if my code for column search of datatables as well as complete search,
$columns = array(0 => 'ship_id' ,
1 => 'sr',
2 => 'ce',
3 => 'sto',
4 => 'supply' ,
5 => 'part',
6 => 'description',
7 => 'quantity',
8 => 'date',
9 => 'shipn',
10 => 'ship',
11 => 'transport',
12 => 'docket',
13 => 'delivery');
if(isset($searchValue) && $searchValue != '')
{
$searchingAll = array();
for($i=0; $i<count($columns); $i++) //Loop search in all defined columns
{
$searchingAll = $this->db->or_like($columns[$i], $searchValue);
$searchingColumns = NULL;
}
}
else if($this->input->post('columns[1][search][value]', TRUE) != '')
{
for($i=0; $i<count($columns); $i++) //Loop search in all defined columns
{
$searchingAll = NULL;
$searchingColumns = $this->db->or_like($columns[1], $this->input->post('columns[1][search][value]', TRUE));
}
}
else
{
$searchingAll = NULL;
$searchingColumns = NULL;
}
First IF condition will search complete datatable, then else-if will search individual column,
I have 12 columns in my datatables, so i need to loop 12 times else-if condition,
In above code currently i shown only column 1, but i need to check all 12 columns that something is entered in any of column search then it will go to for loop of else-if condition,
How can i check all 12 columns in else-if condition?
Thanks,

You were not using the $i you defined in the else if.
Use this instead:
$columns = array(0 => 'ship_id' ,
1 => 'sr',
2 => 'ce',
3 => 'sto',
4 => 'supply' ,
5 => 'part',
6 => 'description',
7 => 'quantity',
8 => 'date',
9 => 'shipn',
10 => 'ship',
11 => 'transport',
12 => 'docket',
13 => 'delivery');
if(isset($searchValue) && $searchValue != '')
{
$searchingAll = array();
for($i=0; $i<count($columns); $i++) //Loop search in all defined columns
{
$searchingAll = $this->db->or_like($columns[$i], $searchValue);
$searchingColumns = NULL;
}
}
else if($this->input->post('columns[1][search][value]', TRUE) != '')
{
for($i=0; $i<count($columns); $i++) //Loop search in all defined columns
{
$searchingAll = NULL;
$searchingColumns = $this->db->or_like($columns[$i], $this->input->post('columns['.$i.'][search][value]', TRUE));
}
}
else
{
$searchingAll = NULL;
$searchingColumns = NULL;
}

Related

Foreach does not return all values

I have a foreach but it only returns the last value and not all the values, what is the problem?
my array
array:1 [▼
"ciudad" => array:15 [▼
0 => "Piura"
1 => "10"
2 => "0"
3 => "Lima"
4 => "20"
5 => "0"
6 => "Pisco"
7 => "30"
8 => "0"
9 => "Arequipa"
10 => "40"
11 => "0"
12 => "Loreto"
13 => "50"
14 => "0"
]
]
My code:
public function updateciudadpreciosdelivery(Request $request)
{
$data = $request->except(['_token', 'restaurant_id']);
$i = 0;
$result = [];
foreach ($data as $day => $times) {
$day_result = [];
foreach ($times as $key => $time) {
if ($key % 3 == 0) {
$day_result["open"] = $time;
}
elseif ($key % 2 == 0) {
$day_result["cod"] = $time;
}
else {
$day_result["close"] = $time;
}
}
$result[$day][] = $day_result;
}
// Fetches The Restaurant
$restaurant = Restaurant::where('id', $request->restaurant_id)->first();
// Enters The Data
if (empty($result)) {
$restaurant->deliveryciudadprecios = null;
}
else {
$restaurant->deliveryciudadprecios = json_encode($result);
}
$restaurant->delivery_charge_type = 'XCIUDAD';
// Saves the Data to Database
$restaurant->save();
return redirect()->back()->with(['success' => 'Las ciudades se guardaron correctamente']);
}
Currently it only returns the last value
"{"ciudad":[{"open":"Loreto","close":"50","cod":"0"}]}"
I need you to return the following (example)
{"ciudad":[{"open" :"Piura","close" :"10","cod" :"0"},{"open" :"Lima","close" :"20","cod" :"0"},{"open" :"Pisco","close" :"30","cod" :"0"},{"open" :"Arequipa","close" :"40","cod" :"0"},{"open" :"Loreto","close" :"50","cod" :"0"}]}
If it is not clear I will try to improve it
If we consider your data won't change, and you have 3 entries to get, you can use array_chunk:
$result = [];
foreach ($data as $day => $times) {
$timesChunked = array_chunk($times, 3);
foreach ($timesChunked as $time) {
$result[$day] []= [
'open' => $time[0],
'close' => $time[1],
'code' => $time[2],
];
}
}
But your problem was logical, you don't change the key in your loop, of course your array will have only the last elements. Reread your code, and try to understand why.

PHP - add values to already existing array

I have a already defined array, containing values just like the one below:
$arr = ['a','b','c'];
How could one add the following using PHP?
$arr = [
'a' => 10,
'b' => 5,
'c' => 21
]
I have tried:
$arr['a'] = 10 but it throws the error: Undefined index: a
I am surely that I do a stupid mistake.. could someone open my eyes?
Full code below:
$finishes = []; //define array to hold finish types
foreach ($projectstages as $stage) {
if ($stage->finish_type) {
if(!in_array($stage->finish_type, $finishes)){
array_push($finishes, $stage->finish_type);
}
}
}
foreach ($projectunits as $unit) {
$data[$i] = [
'id' => $unit->id,
'project_name' => $unit->project_name,
'block_title' => $unit->block_title,
'unit' => $unit->unit,
'core' => $unit->core,
'floor' => $unit->floor,
'unit_type' => $unit->unit_type,
'tenure_type' => $unit->tenure_type,
'floors' => $unit->unit_floors,
'weelchair' => $unit->weelchair,
'dual_aspect' => $unit->dual_aspect
];
$st = array();
$bs = '';
foreach ($projectstages as $stage) {
$projectmeasure = ProjectMeasure::select('measure')
->where('project_id',$this->projectId)
->where('build_stage_id', $stage->id)
->where('unit_id', $unit->id)
->where('block_id', $unit->block_id)
->where('build_stage_type_id', $stage->build_stage_type_id)
->first();
$st += [
'BST-'.$stage->build_stage_type_id => ($projectmeasure ? $projectmeasure->measure : '0')
];
if (($stage->is_square_meter == 0) && ($stage->is_draft == 0)) {
$height = ($stage->height_override == 0 ? $unit->gross_floor_height : $stage->height_override); //08.14.20: override default height if build stage type has it's own custom height
$st += [
'BST-sqm-'.$stage->build_stage_type_id => ($projectmeasure ? $projectmeasure->measure * $height: '0')
];
if ($stage->finish_type) {
$finishes[$stage->finish_type] += ($projectmeasure ? $projectmeasure->measure * $height: '0') * ($stage->both_side ? 2 : 1); //error is thrown at this line
}
} else {
if ($stage->finish_type) {
$finishes[$stage->finish_type] += ($projectmeasure ? $projectmeasure->measure : '0');
}
}
}
$data[$i] = array_merge($data[$i], $st);
$data[$i] = array_merge($data[$i], $finishes[$stage->finish_type]);
$i++;
}
The above code is used as is and the array $finishes is the one from the first example, called $arr
You're using += in your real code instead of =. That tries to do maths to add to an existing value, whereas = can just assign a new index with that value if it doesn't exist.
+= can't do maths to add a number to nothing. You need to check first if the index exists yet. If it doesn't exist, then assign it with an initial value. If it already exists with a value, then you can add the new value to the existing value.
If you want to convert the array of strings to a collection of keys (elements) and values (integers), you can try the following:
$arr = ['a','b','c'];
$newVals = [10, 5, 21];
function convertArr($arr, $newVals){
if(count($arr) == count($newVals)){
$len = count($arr);
for($i = 0; $i < $len; $i++){
$temp = $arr[$i];
$arr[$temp] = $newVals[$i];
unset($arr[$i]);
}
}
return $arr;
}
print_r(convertArr($arr, $newVals));
Output:
Array ( [a] => 10 [b] => 5 [c] => 21 )

Conditional remove adjacent duplicates from array

I have following code that removes adjacent duplicates from the $myArray
<?php
$myArray = array(
0 => 0,
1 => 0,
2 => 1,
5 => 1,
6 => 2,
7 => 2,
8 => 2,
9 => 0,
10 => 0,
);
$previtem= NULL;
$newArray = array_filter(
$myArray,
function ($currentItem) use (&$previtem) {
$p = $previtem;
$previtem= $currentItem;
return $currentItem!== $p ;
}
);
echo "<pre>";
print_r($newArray);
?>
It works perfectly fine, but I have to change a condition bit for value 2. That means for other values we can pick first occurrence and ignore the others. But for 2, we need to pick last occurrence and ignore others.
So required output is
Array
(
[0] => 0 //first occurrence of 0 in $myArray
[2] => 1 //first occurrence of 1 in $myArray
[8] => 2 //last occurrence of 2 in the $myArray
[9] => 0 //first occurrence of 0 in $myArray
)
How to modify my code to achieve above result??
In reality I have multidimensional array, but for better explanation I have used single dimensional array here in the question.
UPDATE
My actual array is
$myArray = array(
0 => array("Value"=>0, "Tax" => "11.00"),
1 => array("Value"=>0, "Tax" => "12.00"),
2 => array("Value"=>1, "Tax" => "13.00"),
5 => array("Value"=>1, "Tax" => "14.00"),
6 => array("Value"=>2, "Tax" => "15.00"),
7 => array("Value"=>2, "Tax" => "16.00"),
8 => array("Value"=>2, "Tax" => "17.00"),
9 => array("Value"=>0, "Tax" => "18.00"),
10 => array("Value"=>0, "Tax" => "19.00"),
);
And my actual code
$previtem= NULL;
$newArray = array_filter(
$myArray,
function ($currentItem) use (&$previtem) {
$p["Value"] = $previtem["Value"];
$previtem["Value"] = $currentItem["Value"];
return $currentItem["Value"]!== $p["Value"] ;
}
);
Thanks
This should do what you are looking for.
function array_filter($a) {
$na = array();
$first = true;
$p = null;
$wantlast = false;
foreach ($a as $v) {
if ($wantlast) {
($v != $p) ? $na[] = $p: null;
}
$wantlast = ($v == 2) ? true : false;
if (!$wantlast) {
(($v != $p) || ($first))? $na[] = $v : null;
}
$p = $v;
$first = false;
}
return $na;
}
$myArray = array(
0 => 0,
1 => 0,
2 => 1,
5 => 1,
6 => 2,
7 => 2,
8 => 2,
9 => 0,
10 => 0,
);
$previtem= NULL;
$newArray = array_filter(
$myArray,
function ($currentItem, $key) use (&$previtem,$myArray) {
$p = $previtem;
if($currentItem != 2){
$previtem = $currentItem;
}else{
$lastkey = array_search(2,(array_reverse($myArray, true)));
if($key != $lastkey)
$currentItem = $previtem;
}
return $currentItem!== $p ;
}, ARRAY_FILTER_USE_BOTH
);
echo "<pre>";
print_r($newArray);

PHP & Array: count distance between two keys

Having an array similar to the one below:
$steps = array(0 => 'aaa', 1 => 'bbb', 2 => 'ccc', ......, 7 => 'hhh', 8 => 'iii', .....);
How can I calculate how many steps (key) do I need to reach key 2 from key 7 respecting the sequence?
If you have numeric keys that never have any missing numbers, you can use basic subtraction.
If you need to account for possible missing numbers, or the keys are not numeric, you can use a combination of array_keys() and array_search():
$array = array(
0 => 'aaa',
1 => 'bbb',
3 => 'ccc',
'four' => 'ddd',
900 => 'eee',
13 => 'fff'
);
$from = 1;
$to = 900;
$keys = array_keys($array);
$from_index = array_search($from, $keys); // 1
$to_index = array_search($to, $keys); // 4
$steps = $to_index - $from_index;
// 3 steps: from 1-3, from 3-'four' and from 'four'-900
I solved this problem by writing this code:
$tot_step = 0;
$steps = array(
0 => 'aaa',
1 => 'bbb',
2 => 'ccc',
3 => 'ddd',
4 => 'eee',
5 => 'fff',
6 => 'ggg',
7 => 'hhh',
8 => 'iii',
9 => 'jjj',
10 => 'aaa'
);
$from = "ddd";
$to = "bbb";
$from_index = array_search($from, $steps);
$to_index = array_search($to, $steps);
$last = $steps[(count($steps)-1)];
if ($from_index > 0) {
if ($to == $last)
$to_index = (count($steps)-1);
$arr_l = count($steps);
$mila = array();
for ($ind = $from_index; $ind <= ($arr_l-1); $ind++) {
if ($to == $last) {
if ($steps[$ind] != $last)
$mila[] = $steps[$ind];
} else {
$mila[] = $steps[$ind];
}
unset($steps[$ind]);
}
if (!empty($mila)) {
for ($i = (count($mila)-1); $i >= 0; $i--)
array_unshift($steps, $mila[$i]);
}
$to_new = array_search($to, $steps);
foreach ($steps as $key => $value) {
if ($key == $to_new)
break;
else
$tot_step++;
}
} elseif ($from_index == 0) {
if ($to_index == $from_index) {
$tot_step = (count($steps)-1);
} else {
foreach ($steps as $key => $value) {
if ($key == $to_index)
break;
else
$tot_step++;
}
}
}
echo $tot_step;
I hope it will be useful to someone

Symfony2 undefined offset: 0 error with lottery project

In my lottery project I have 5 tickets, in which you select numbers and buy. The thing is, you can only buy the tickets if you buy them in order... For example:
Ticket 1 Ticket 2 Ticket 3 Ticket 4 Ticket 5
If you add numbers to the ticket 1 and then the others it works... If you skip the ticket 1 and add numbers to the other ones, when you try to buy you get this error:
ContextErrorException: Notice: Undefined offset: 0 in C:\wamp\www\Digidis\front\src\MediaparkLt\UserBundle\Service\MoneyManager.php line 313
The full stack:
array('cartProduct' => array('title' => 'EUROMILLONES', 'price' => '2.35', 'product' => '2', 'ticket_id' => '1433921783_19792', 'numbers' => '8,13,14,17,37', 'stars' => '4,7', 'betslip' => '{"duration":"1","subscription":"false","jsPrice":"235","type":"simple","numbers1":"0,0,0,0,0","numbers2":"8,13,14,17,37","numbers3":"0,0,0,0,0","numbers4":"0,0,0,0,0","numbers5":"0,0,0,0,0","stars1":"0,0","stars2":"4,7","stars3":"0,0","stars4":"0,0","stars5":"0,0","dayOfWeek":"3"}', 'is_syndicate' => false, 'draw' => object(DateTime)), 'product' => object(Product), 'user' => object(User), 'reference' => null, 'paymentResult' => 'Authorised', 'bets' => object(stdClass), 'individualBets' => array(), 'tickets' => array(array('numbers' => '8,13,14,17,37', 'stars' => '4,7')), 'k' => '0', 't' => array('numbers' => '0,0,0,0,0', 'stars' => '0,0'), 'is_ticket_filled' => false, 'week_id' => array(array('ticketId' => '7005')), 'g' => '0', 'lastId' => '7005', 'purchase' => object(Purchase), 'price' => '2.35', 'bet' => object(Bet), 'euromillonesBet' => object(EuromillonesBet), 'drawDate' => array(object(DrawDate)), 'j' => '0')) in C:\wamp\www\Digidis\front\src\MediaparkLt\UserBundle\Service\MoneyManager.php line 313
As you can see first it gets the ticket 1, which is empty(or 0) and thats why it causes the error... How can I make it so that it skips the empty tickets?
Here is the controller where the error occurs:
$bets = json_decode($cartProduct['betslip']);
$individualBets = array();
$tickets = array(
array('numbers' => $bets->numbers1, 'stars' => $bets->stars1),
array('numbers' => $bets->numbers2, 'stars' => $bets->stars2),
array('numbers' => $bets->numbers3, 'stars' => $bets->stars3),
array('numbers' => $bets->numbers4, 'stars' => $bets->stars4),
array('numbers' => $bets->numbers5, 'stars' => $bets->stars5)
);
if ($bets->type === 'simple') {
foreach ($tickets as $k => $t) {
$is_ticket_filled = ((int) str_replace(',', '', $t['numbers'])) > 0;
if (!$is_ticket_filled) {
unset($tickets[$k]);
}
}
} else if ($bets->type === 'multiple') {
$tickets = array(array('numbers' => $bets->numbers1, 'stars' => $bets->stars1));
}
$week_id = null;
for ($k = 0; $k < (count($tickets)); $k++) {
for ($g = 0; $g < $bets->duration; $g++) {
if (!isset($week_id[$g])) {
$week_id[$g] = $this->entityManager->getRepository('MediaparkLtLotteryBundle:Bet')->getLastTicketId();
if ($week_id[$g]) {
$week_id[$g]['ticketId'] ++;
} else {
$week_id[$g]['ticketId'] = 0;
}
}
$lastId = $week_id[$g]['ticketId'];
$purchase = new Purchase();
$purchase->setUser($user);
$purchase->setDrawDate($cartProduct['draw']);
$purchase->setProduct($product);
$purchase->setReference($reference);
$price = $cartProduct['price'];
$bet = new Bet();
if ('eurojackpot' == $product->getAlias()) {
$euromillonesBet = new EurojackpotBet();
} else {
$euromillonesBet = new EuromillonesBet();
}
$drawDate = $this->entityManager->getRepository('MediaparkLtLotteryBundle:DrawDate')->findByDrawDate($cartProduct['draw']);
if (!$drawDate)
die('no draw date found ' . $cartProduct['draw']->format('Y-m-d H:i:s'));
$bet->setDrawDate($drawDate[0]);
$bet->setTicketId($lastId);
if (strtoupper($paymentResult) === 'AUTHORISED') {
$bet->setStatus(BetStatus::AUTHORISED);
} else {
$bet->setStatus(BetStatus::FAILED);
}
$bet->setWinnings(0);
$euromillonesBet->setBet($bet);
/// LINE 313 ABOVE!!!!!!!
$numbers = $this->getNumbersArray($tickets[$k]['numbers']);
$j = 0;
foreach ($numbers as $number) {
$j++;
$name = 'setN' . $j;
$euromillonesBet->$name($number);
}
$numbers = $this->getNumbersArray($tickets[$k]['stars']);
$euromillonesBet->setS1($numbers[0]);
$euromillonesBet->setS2($numbers[1]);
$euromillonesBet->setAmountOfStars(Bet::NUMBER_OF_STARS);
$purchase->addBet($bet);
$purchase->setPricePaid($price);
if (strtoupper($paymentResult) === 'AUTHORISED') {
$purchase->setStatus(PaymentStatus::AUTHORISED);
} else {
$purchase->setStatus(PaymentStatus::FAILED);
}
if ($bets->subscription === "true") {
$contract = new PurchaseContract();
$contract->setAccumulatedWinnings(0);
$contract->setCancellationDate(null);
$contract->setFirstDrawDate($purchase->getDrawDate());
$contract->setLastRenewedDate($purchase->getDrawDate());
$contract->setNextRenewalFirstDrawDate($purchase->getDrawDate());
// $contract->setPurchase($purchase);
$contract->setStatusPurchaseContract(1);
$contract->setWeeks(1);
$purchase->setPurchaseContract($contract);
$this->entityManager->persist($contract);
}
if ($g == 0)
$individualBets[] = $euromillonesBet;
$this->entityManager->persist($bet);
$this->entityManager->persist($euromillonesBet);
$this->entityManager->persist($purchase);
$this->entityManager->flush();
}
}
return $individualBets;
}
From what I see the bet type in your object is set to "type":"simple" and numbers1":"0,0,0,0,0"
$is_ticket_filled = ((int) str_replace(',', '', $t['numbers'])) > 0;
//(int) 00000 = 0
if (!$is_ticket_filled) {
unset($tickets[$k]);
}
Is causing the issue since unset does not reset the array indexes.
http://ideone.com/5q74Wv
Then later you iterate using for($k=0; $k < count($tickets); $k++)
You should instead rebase the array after using unset($tickets[$k])
if ($bets->type === 'simple') {
//...
$tickets = array_values($tickets);
}
or check the existence of the ticket when iterating over indexes
$ticketCount = count($tickets);
for ($k=0; $k < $ticketCount; $k++) {
if (false === isset($tickets[$k]) {
continue;
}
//...
}
or easier still, iterate over the existing tickets array using foreach instead of for.
foreach ($tickets as $k => $ticket) {
//...
}
Then change $tickets[$k] with just $ticket since $k is not used anywhere else.

Categories