Logical algorithm to generate paths - algorithm

I'm trying to develop an algorithm to create a symfony template service.
I want to check if a template exists in a subset of paths, ordered.
Given an array of parameter like this (already ordered like I want):
$params = ['O', 'U', 'W', 'P']
How can I output this array?
$urls = [
'O/U/W/P/template',
'O/U/W/template',
'O/U/P/template',
'O/U/template',
'O/W/P/template',
'O/W/template',
'O/P/template',
'O/template',
'U/W/P/template',
'U/W/template',
'U/P/template',
'U/template',
'W/P/template',
'W/template',
'P/template',
'template'
];
I can perform for a little list of parameters (like everyone can do it I suppose) with a code like this :
private function getPaths($template, $params)
{
$urls = [];
$alreadyPerform = [];
$paramsCounter = count($params);
for ($i = 0; $i < $paramsCounter; $i++) {
for ($j = 0; $j < $paramsCounter; $j++) {
if ($i !== $j && !in_array($params[$j], $alreadyPerform, true)) {
$urls[] = sprintf(
'/%s/%s/%s.html.twig', $params[$i], $params[$j], $template
);
}
}
$alreadyPerform[] = $params[$i];
$urls[] = sprintf('/%s/%s.html.twig', $params[$i], $template);
}
$urls[] = sprintf('%s.html.twig', $template);
return $urls;
}
This function work like I wanted until today (max 3 parameters), but I want to add one parameters today, maybe more after.
Thank you very much for your help !
Cheers.

Using recursion, you can do the following:
/**
* #param array $elements
* #param array $extra
*
* #return Generator
*/
function gen(array $elements, array $extra = []): \Generator {
foreach ($elements as $i => $head) {
foreach (gen(array_slice($elements, $i + 1), $extra) as $tail) {
yield array_merge([$head], $tail);
}
}
yield $extra;
}
demo: https://3v4l.org/gJB8q
Or without recursion:
/**
* #param array $elements
*
* #return Generator
*/
function gen2(array $elements): \Generator {
for ($num = count($elements), $i = pow(2, $num) - 1; $i >= 1; $i -= 2) {
$r = [];
for ($j = 0; $j < $num; $j += 1) {
if ($i & (1 << ($num - $j - 1))) {
$r[] = $elements[$j];
}
}
yield $r;
}
}
demo: https://3v4l.org/grKXo

Consider using the following package:
https://github.com/drupol/phpermutations
Just a very basic example of what it can do:
$permutations = new \drupol\phpermutations\Generators\Permutations(['A', 'B', 'C'], 2);
foreach ($permutations->generator() as $permutation) {
echo implode('/', $permutation);
echo "\n";
}
A/B
B/A
A/C
C/A
B/C
C/B

Related

Ascending order of fetched data

I am fetching count. My target is to display it in ASCENDING ORDER. i have tried to sort it using sort($match); but i have still failed to achieve my goal. Thank you. Any help will be appreciated
Controller:
function asdasdas(){
$entry= $this->repo->entryfetch();
$data='<table>
<thead><tr><th>NO. </th></tr></thead>';
foreach($entry as $entry){
$match= $this->repo->matchfetch($entry->handlerID);
$data.='<thead><tr><th><hr>'.$entry->handlerID.' '.$entry->entryName.'</th> ';
foreach($match as $match){
$diff = $match->weightM - $match->weightW;
if($match->handlerIDM === $entry->handlerID){
$name=$match->handlertestW;
$count=$match->countM;
}else{
$name=$match->handlerM;
$count=$match->countW;
}
$data.='<tbody><tr><td>'.$count.'</td>';
$data.='<td></td></tr></tbody>';
//
}
}
$data .='<table>';
echo $data;
sort($match); // i have tried to sort it using this but it is not working.
}
You can loop the array from the last index to 0
function asdasdas()
{
$entry = $this->repo->entryfetch();
$data = '<table>
<thead><tr><th>NO. </th></tr></thead>';
for ($j = count($entry) - 1; $j >= 0; $j--) {
$match = $this->repo->matchfetch($entry[$j]->handlerID);
$data .= '<thead><tr><th><hr>' . $entry[$j]->handlerID . ' ' . $entry[$j]->entryName . '</th> ';
for ($i = count($match) - 1; $i >= 0; $i--) {
$diff = $match[$i]->weightM - $match[$i]->weightW;
if ($match[$i]->handlerIDM === $entry[$j]->handlerID) {
$name = $match[$i]->handlertestW;
$count = $match[$i]->countM;
} else {
$name = $match[$i]->handlerM;
$count = $match[$i]->countW;
}
$data .= '<tbody><tr><td>' . $count . '</td>';
$data .= '<td></td></tr></tbody>';
}
}
$data .= '<table>';
echo $data;
}
Context is not much clear. Do you need to sort $match before for loop or while inside the forloop. Can you explain a bit if haven't got the solution.

how to update the value of the variable in laravel controller every time the function is called

public function index()
{
$a = 1;
$b = 2;
$c = 3;
$x = array($a,$b,$c);
if($x == range(1,3)) {
print_r("hello");
}
for($i = 0; $i < 3; $i++) {
$x[$i] += $x[2];
}
$a = $x[0];
$b = $x[1];
$c = $x[2];
}
I want every time the function is called $x[] should be update with new values ( like $a = $x[0];)
Something like this.
public function index(Request $request)
{
$a = $request->session()->get('a') ?: 1;
$b = $request->session()->get('b') ?: 2;
$c = $request->session()->get('c') ?: 3;
$x = array($a,$b,$c);
if($x == range(1,3)) {
print_r("hello");
}
for($i = 0; $i < 3; $i++) {
$x[$i] += $x[2];
}
$a = $x[0];
$b = $x[1];
$c = $x[2];
$request->session()->put('a', $a);
$request->session()->put('b', $b);
$request->session()->put('c', $c);
}

How to pluck a value from foreach statement in Laravel

I am getting an array from database table and through a for each statement. Then check the difference between two values if there is any difference that is less than zero sets a value to 0 for that loop. Then do the same with the next loop.
$bom_id = App\Models\Bom::where('item_id', $item->order_item->id)->pluck('id')->first();
if ($bom_id > 0) {
$bomList = App\Models\Bom_list::where('bom_id', $bom_id)->get();
echo '<div class="row">';
foreach ($bomList as $bomlist) {
$availableQty = $item->order_item->qty;
$requiredQty = $bomlist->qty * $item->qty;
$dif = $availableQty - $requiredQty;
}
$check = '';
$arr = array($bomlist->$dif);
$light = in_array($check, $arr, true) ? 0 : 1;
} else {
$light = 0;
}
enter image description here

Get formatted values from custom Form Request - Laravel 5.6

I`m using custom form request to validate all input data to store users.
I need validate the input before send to form request, and get all validated data in my controller.
I have a regex function ready to validate this input, removing unwanted characters, spaces, allow only numbers and etc.
Would to get all data validated in controller, but still have no success.
Input example:
$cnpj= 29.258.602/0001-25
How i need in controller:
$cnpj= 29258602000125
UsuarioController
class UsuarioController extends BaseController
{
public function cadastrarUsuarioExterno(UsuarioStoreFormRequest $request)
{
//Would to get all input validated - no spaces, no!##$%^&*, etc
$validated = $request->validated();
dd($data);
}
...
}
UsuarioStoreFormRequest
<?php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Http\Request;
class UsuarioStoreFormRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*
* #return bool
*/
public function authorize()
{
return true;
}
/**
* Get the validation rules that apply to the request.
*
* #return array
*/
public function rules()
{
return [
'cnpj' => 'required|numeric|digits:14',
];
}
Custom function to validate cnpj
function validar_cnpj($cnpj)
{
$cnpj = preg_replace('/[^0-9]/', '', (string) $cnpj);
// Valida tamanho
if (strlen($cnpj) != 14)
return false;
// Valida primeiro dígito verificador
for ($i = 0, $j = 5, $soma = 0; $i < 12; $i++)
{
$soma += $cnpj{$i} * $j;
$j = ($j == 2) ? 9 : $j - 1;
}
$resto = $soma % 11;
if ($cnpj{12} != ($resto < 2 ? 0 : 11 - $resto))
return false;
// Valida segundo dígito verificador
for ($i = 0, $j = 6, $soma = 0; $i < 13; $i++)
{
$soma += $cnpj{$i} * $j;
$j = ($j == 2) ? 9 : $j - 1;
}
$resto = $soma % 11;
return $cnpj{13} == ($resto < 2 ? 0 : 11 - $resto);
}
You could use the prepareForValidation method in your FormRequest. This way your input would be modified and replaced in the request before it is validated and you can normally retrieve it in the controller with $request->get('cnpj'); after the validation was successful.
public function prepareForValidation()
{
$input = $this->all();
if ($this->has('cnpj')) {
$input['cnpj'] = $this->get('cnpj'); // Modify input here
}
$this->replace($input);
}
You could extend the validated function in UsuarioStoreFormRequest as follows
/**
* Get the validated data from the request.
*
* #return array
*/
public function validated()
{
$validated = parent::validated();
//Add here more characters to remove or use a regex
$validated['cnpj'] = str_replace(['-', '/', ' ', '.'], '', $validated['cnpj']);
return $validated;
}
Do it like this:
$string = "29.258.602/0001-25";
preg_match_all('!\d+!', $string, $matches);
return (implode("",$matches[0]));
Hope its help

Laravel Model Average of Non-N/A Values

I am looking for the best way to average the values of a submodel in Laravel, but ignore some of the values. The column I want to average is set as varchar, but contains either a number between 0 and 10 or the value 'N/A'. I need two averages on this column, one ignoring 'N/A' values, and one counting 'N/A' values as 0. I have the fucntions written how how they would be to calculate the averages but I am hoping to get some input on the best way to do this.
I would love to be able to call these functions like this:
$web_scored_tq = $website->scored_tq;
$web_uscored_tq = $website->unscored_tq;
Functions:
public function scored_tq() {
$valid_click_ads = $this->valid_click_ads;
$total = 0;
$num = 0;
foreach ($valid_click_ads as $valid_click_ad) {
if ($valid_click_ad->tq != "N/A") {
$total += $valid_click_ad->tq;
++$num;
}
}
$scored_tq = $total / $num;
}
public function unscored_tq() {
$valid_click_ads = $this->valid_click_ads;
$total = 0;
$num = 0;
foreach ($valid_click_ads as $valid_click_ad) {
if ($valid_click_ad->tq != "N/A") {
$total += $valid_click_ad->tq;
++$num;
} else {
++$num;
}
}
$unscored_tq = $total / $num;
}
I found laravel's model getFooAttribute! I used this to add the following functions to my Website model, and now can call $website->scored_tq or $website->unscored_tq.
public function getScoredTqAttribute() {
$valid_click_ads = $this->valid_click_ads;
$total = 0;
$num = 0;
foreach ($valid_click_ads as $valid_click_ad) {
if ($valid_click_ad->tq != -1) {
$total += $valid_click_ad->tq;
++$num;
}
}
if ( $num != 0 ) {
$scored_tq = $total / $num;
} else {
$scored_tq = '-';
}
return $scored_tq;
}
public function getUnscoredTqAttribute() {
$valid_click_ads = $this->valid_click_ads;
$total = 0;
$num = 0;
foreach ($valid_click_ads as $valid_click_ad) {
if ($valid_click_ad->tq != -1) {
$total += $valid_click_ad->tq;
}
++$num;
}
if ( $num != 0 ) {
$unscored_tq = $total / $num;
} else {
$unscored_tq = '-';
}
return $unscored_tq;
}
I also changed how my data is structured to integers, where "N/A" values are changed to -1.

Resources