I want to separate numbers, like a serial number, ex:
I've got 1-1000,
if I want to remove 1-100, then I will get 101-1000
if I want to remove 901-1000, then I will get 1-900
if I want to remove 101-200 then I will get 1-100 and 201-1000
and so on.
I just insert first number and last number, like 1 and 100.
The problem is, I am using MySQL to store data, this is my tables:
[items(id,name), serials(id,name), details(id,item_id,serial_id,first,last)][1]
I've a solution, but I think my solution is too long and isn't efficient for my code if I work with large data, this is my solution
public function checkSerialNum(array $data){
$item_id = $data['item_id'];
$serial_id = $data['serial_id'];
$first = $data['first'];
$last = $data['last'];
if($first > $last) return false;
$sql = "SELECT * FROM details WHERE item_id = '$item_id' AND serial_id = '$serial_id'";
$details = $this->db->run($sql)->fetchAll();
$new_detail = [];
foreach($details as $key => $detail){
if($first == $detail->first && $last == $detail->last){ // 1 - 1000 -> 0 - 0
$new_detail['item_id'][] = $item_id;
$new_detail['serial_id'][] = $serial_id;
$new_detail['first'][] = 0;
$new_detail['last'][] = 0;
$new_detail['old_id'][] = $detail->id;
}elseif($first > $detail->first && $last == $detail->last){ // 901-1000 -> 1 - 900
$new_detail['item_id'][] = $item_id;
$new_detail['serial_id'][] = $serial_id;
$new_detail['first'][] = $detail->first;
$new_detail['last'][] = $first - 1;
$new_detail['old_id'][] = $detail->id;
}elseif($first == $detail->first && $last < $detail->last){ // 1 - 100 -> 101 - 1000
$new_detail['item_id'][] = $item_id;
$new_detail['serial_id'][] = $serial_id;
$new_detail['first'][] = $last + 1;
$new_detail['last'][] = $detail->last;
$new_detail['old_id'][] = $detail->id;
}elseif($first > $detail->first && $last < $detail->last){ //101-200 -> 1-100 & 201-1000
$new_detail['item_id'][] = $item_id;
$new_detail['serial_id'][] = $serial_id;
$new_detail['first'][] = $detail->first;
$new_detail['last'][] = $first - 1;
$new_detail['old_id'][] = $detail->id;
$new_detail['item_id'][] = $item_id;
$new_detail['serial_id'][] = $serial_id;
$new_detail['first'][] = $last + 1;
$new_detail['last'][] = $detail->last;
}
}
return $this->tidyArray($new_detail);
}
public function tidyArray($arr){
$new_arr = [];
foreach($arr as $k => $array){
for($i=0;$i < count($array); $i++){
$new_arr[$i][$k] = $array[$i];
}
}
return $new_arr;
}
public function removeSerialNum(array $data){ //
$new_details = $this->checkSerialNum($data);
if(!$new_details) return false;
$item_id = $data['item_id'];
$serial_id = $data['serial_id'];
foreach($new_details as $nd){
if(isset($nd['old_id'])){
$old_id = $nd['old_id'];
$sql = "DELETE FROM details WHERE item_id = '$item_id' AND serial_id = '$serial_id' AND id = '$old_id'";
$this->db->run($sql);
unset($nd['old_id']);
}
$this->insertData('details',$nd);
}
return true;
}
}
The $data is returning something like this
$data = [
'first' => 1,
'last' => 100,
'item_id' => 1,
'serial_id' => 1
];
The function tidyArray() is changing the format array from something like this:
////// it will return like this if I'm not breaking any range, like I've 821-900 and I just input 821-850
Array
(
[item_id] => Array
(
[0] => 1
)
[serial_id] => Array
(
[0] => 1
)
[first] => Array
(
[0] => 821
)
[last] => Array
(
[0] => 850
)
[old_id] => Array
(
[0] => 8
)
)
/////but if I've 821-900 and input like 851-860, it will return like this
Array
(
[item_id] => Array
(
[0] => 1
[1] => 1
)
[serial_id] => Array
(
[0] => 1
[1] => 1
)
[first] => Array
(
[0] => 821
[1] => 861
)
[last] => Array
(
[0] => 850
[1] => 900
)
[old_id] => Array
(
[0] => 10
)
)
to something like this:
//////it will return like this if I'm not breaking any range, like I've 821-900 and I just input 821-850
Array
(
[0] => Array
(
[item_id] => 1
[serial_id] => 1
[first] => 811
[last] => 900
[old_id] => 8
)
)
/////but if I've 821-900 and input like 851-860, it will return like this, its like new range of data, I will explain old_id below..
Array
(
[0] => Array
(
[item_id] => 1
[serial_id] => 1
[first] => 821
[last] => 850
[old_id] => 10
)
[1] => Array
(
[item_id] => 1
[serial_id] => 1
[first] => 861
[last] => 900
)
)
and the last is function removeSerialNum() this will delete the affected range of number, example I've 101-200, 301-900 in my database, then I want to remove 151-160, so it will select using the affected row and that's 101-200 row then delete it and change with a new one, this is my data from the array above, this will explain what old_id use for:
"id" "item_id" "serial_id" "first" "last"
"3" "1" "1" "101" "150"
"4" "1" "1" "161" "200"
"5" "1" "1" "301" "350"
"7" "1" "1" "701" "800"
"9" "1" "1" "802" "810"
"10" "1" "1" "821" "900" ->the affected row
in case you wonder what is function insertData() looks like:
public function insertData($table,array $data){
$sql = "INSERT INTO $table SET ";
$vals = [];
foreach($data as $key => $val){
$vals[] = "$key = '$val'";
}
$sql .= implode(',',$vals);
return $this->db->run($sql);
}
This solution is working for me and I just want to ask how can I get a same result but with less lines of code or in a smarter way.
I am having trouble to get the target result of an array.
What I am trying to do is:
push every variables in $inner_data in every loop.
then push that $inner_data to $details_data to create an array inside an array
I hope I explain my idea and problem.
Code
$details_data = array();
$inner_data = array();
for($i=0; $i < $count_selected; $i++){
$amount[$i] = $quantity[$i] * $price[$i];
array_push($inner_data, $last_insert_id, $amount[$i], $quantity[$i], $products[$i]);
array_push($details_data, $inner_data);
}
print_r($details_data); exit;
Target result
$data = array(
array(
'last_insert_id' => 10,
'amount' => 20000,
'quantity' => 1,
'product_id' => 1
),
array(
'last_insert_id' => 10,
'amount' => 1000,
'quantity' => 1,
'product_id' => 2
)
);
Unexpected Result
Array
(
[0] => Array
(
[0] => 10
[1] => 20000
[2] => 1
[3] => 1
)
[1] => Array
(
[0] => 10
[1] => 20000
[2] => 1
[3] => 1
[4] => 10
[5] => 10000
[6] => 1
[7] => 2
)
)
for($i=0; $i < $count_selected; $i++){
$amount[$i] = $quantity[$i] * $price[$i];
$inner_data=array(
'last_insert_id'=>$last_insert_id,
'amount'=>$amount[$i],
'quantity'=>$quantity[$i],
'product_id'=>$products[$i]
);
array_push($details_data, $inner_data);
}
Link for your reference
<?php
$details_data = array();
/* do not set it as a global vari OR clear it when you re-use it */
//$inner_data = array();
$last_insert_id = 10;
$amount = [20000, 1000];
$quantity = [110, 220];
$price = [32, 64];
$products = [001, 002];
for($i=0; $i < 2; $i++){
$amount[$i] = $quantity[$i] * $price[$i];
/* set it here as a local vari, thus it won't accumulate the result */
$inner_data = array();
//array_push($inner_data, $last_insert_id, $amount[$i], $quantity[$i], $products[$i]);
$inner_data['last_insert_id'] = $last_insert_id;
$inner_data['amount'] = $amount[$i];
$inner_data['quantity'] = $quantity[$i];
$inner_data['product_id'] = $products[$i];
array_push($details_data, $inner_data);
}
echo "<pre>";
print_r($details_data); exit;
echo "</pre>";
?>
array_push($details_data,
array('last_insert_id'=>$last_insert_id, 'amount'=>$amount[$i], 'quantity'=>$quantity[$i], 'product_id'=>$products[$i])
);
Try to push an array directly to details_data.
In my attempt to find the perfect ranking solution with ties, I was stuck at giving the correct ranking. Codes will explain what I am trying to achieve better:
I have the following array:
$standings = array(
'player_1' => 30,
'player_2' => 26,
'player_3' => 28,
'player_9' => 28
);
Now in order to rank it with ties, I have the following function:
function setRanking($standings) {
$rankings = array();
arsort($standings);
$rank = 1;
$tie_rank = 0;
$prev_score = -1;
foreach ($standings as $name => $score) {
if ($score != $prev_score) { //this score is not a tie
$count = 0;
$prev_score = $score;
$rankings[$name] = array('score' => $score, 'rank' => $rank);
} else { //this score is a tie
$prev_score = $score;
if ($count++ == 0) {
$tie_rank = $rank - 1;
}
$rankings[$name] = array('score' => $score, 'rank' => $tie_rank);
}
$rank++;
}
return $rankings;
}
echo '<pre>';
print_r(setRanking($standings));
Output:
Array
(
[player_1] => Array
(
[score] => 30
[rank] => 1
)
[player_3] => Array
(
[score] => 28
[rank] => 2
)
[player_9] => Array
(
[score] => 28
[rank] => 2
)
[player_2] => Array
(
[score] => 26
[rank] => 4
)
)
Expected Output:
Array
(
[player_1] => Array
(
[score] => 30
[rank] => 1
)
[player_3] => Array
(
[score] => 28
[rank] => 2
)
[player_9] => Array
(
[score] => 28
[rank] => 2
)
[player_2] => Array
(
[score] => 26
[rank] => 3
)
)
The problem is it prints the ranking as 1,2,2,4 whereas it should print 1,2,2,3 according to my assumption. So how can it print 1,2,2,3? Where could thing possibly go wrong? Any help is appreciated. Thanks.
Just change your else block, You are not decrements your $rank value so its hold the same value as it is. You just do the $rank - 1 cause its just less 1 to store in a variable not change the main value.
foreach ($standings as $name => $score) {
if ($score != $prev_score) { //this score is not a tie
$count = 0;
$prev_score = $score;
$rankings[$name] = array('score' => $score, 'rank' => $rank);
} else { //this score is a tie
$prev_score = $score;
$rank--; // Decrements here
if ($count++ == 0) {
$tie_rank = $rank;
}
$rankings[$name] = array('score' => $score, 'rank' => $tie_rank);
}
$rank++;
}
return $rankings;
i have been troubling to format array correctly
i have this code:
require('simple_html_dom.php');
$table = array();
$html = file_get_html('apc.html');
foreach($html->find('tr') as $row) {
$rack = ltrim($row->find('td',0)->plaintext);
$location = ltrim($row->find('td',1)->plaintext);
$usage = ltrim($row->find('td',2)->plaintext);
$auk = ltrim($row->find('td',3)->plaintext);
$cost = ltrim($row->find('td',4)->plaintext);
$rack = rtrim($rack);
$location = rtrim($location);
$usage = rtrim($usage);
$auk = rtrim($auk);
$cost = rtrim($cost);
$table[$rack][$usage][$auk][$cost] = true;
}
echo '<pre>';
print_r($table);
echo '</pre>';
using simple_html_dom above i can convert html table to an array as follow:
[Rack01] => Array
(
[741,60] => Array
(
[1.409,04] => Array
(
[267,72] => 1
)
)
[110,88] => Array
(
[210,67] => Array
(
[40,03] => 1
)
)
)
[Rack 09] => Array
(
[843,84] => Array
(
[1.603,30] => Array
(
[304,63] => 1
)
)
)
I would like to have result as below:
array(
[0] => array (
[usage] => 'Rack 01',
[usage] => '741,60',
[auk] => '1.409.04',
[cost] => '267,72')
[1] => array (
[usage] => 'Rack 02',
[usage] => 'value???',
[auk] => 'value???',
[cost] => 'value???')
any help would be apreaciate
Something like this. Also note that trim will do both left and right:
foreach($html->find('tr') as $row) {
$rack = trim($row->find('td',0)->plaintext);
$location = trim($row->find('td',1)->plaintext);
$usage = trim($row->find('td',2)->plaintext);
$auk = trim($row->find('td',3)->plaintext);
$cost = trim($row->find('td',4)->plaintext);
$table[] = array('rack' => $rack,
'usage' => $usage,
'auk' => $auk,
'cost' => $cost);
}
Hello Here is my solution as i took some advice about the SQL statement ... thank you all
$connection = ConnectionBD();
$tag = $_SESSION['nomUtilisateur'];
$panier= array();
$requete = mysql_query("SELECT * FROM cours INNER JOIN elevecours ON cours.idcours = elevecours.IDCours WHERE elevecours.IDEleve= '$tag'",$connection);
$H = 0;
if(mysql_num_rows($requete) != 0)
{
while($row = mysql_fetch_row($requete))
{
//$panier[] = $row;
$_SESSION['Panier']['Id'][$H] = $row[0];
$_SESSION['Panier']['CodeCours'][$H] = $row[1];
$_SESSION['Panier']['Titre'][$H] = $row[2];
$_SESSION['Panier']['Prealable'][$H] = $row[3];
$_SESSION['Panier']['NbHeure'][$H] = $row[4];
$_SESSION['Panier']['Session'][$H] = $row[5];
$_SESSION['Panier']['Credit'][$H] = $row[6];
$H ++;
}
}
mysql_close($connection);
You need to mysql_fetch_row once per iteration in your loop.
for($i = 0; $i < mysql_num_rows($req); $i++) {
$resultat = mysql_fetch_row($req);
//the rest of your code goes here
}
Inside your second foreach loop you are setting $H = 0; and then $H++ inside the same loop, this will not increment properly as the next time it goes over the loop again the $H = 0; statement will result this to 0 and therefore keep overwriting your data until the loop is done and you're left with only one $_SESSION value at the end.
for($j = 0; $j < count($panier); $j++)
{
if($resultat[$i] == $panier[$j][0])
{
$H = 0; <-- sets to zero on every interation
$_SESSION['Panier']['Id'][$H] = $result[0];
$_SESSION['Panier']['CodeCours'][$H] = $result[1];
$_SESSION['Panier']['Titre'][$H] = $result[2];
$_SESSION['Panier']['Prealable'][$H] = $result[3];
$_SESSION['Panier']['NbHeure'][$H] = $result[4];
$_SESSION['Panier']['Session'][$H] = $result[5];
$_SESSION['Panier']['Credit'][$H] = $result[6];
$H++;
}
}
Suggest you move this outside your loop if the intention is to iterate the $H variable.
these are my testing variables...
$session = array();
$panier = array(array(1,'one'),array(2,'two'),array(3,'three'),);
$req = array(
array(1,'one','Titre1','Prealable1','NbHeure1','Session1','Credit1'),
array(2,'two','Titre2','Prealable2','NbHeure2','Session2','Credit2'),
array(3,'three','Titre3','Prealable3','NbHeure3','Session3','Credit3'),
array(4,'four','Titre4','Prealable4','NbHeure4','Session4','Credit4'),
array(5,'five','Titre5','Prealable5','NbHeure5','Session5','Credit5'),);
i wrote the code to not rely on your DB and data exactly, since I don't know what it is... dunno. switch out some of these lines of code to use your database stuff.
// $req = mysql_query("SELECT * FROM cours", $connection); uncomment this line for your code
if ($req!==false)
{
foreach( $req as $i => $resultat ) // testing row, remove for real
// while( $resultat = mysql_fetch_row($req) ) // real row, uncomment for you
{
$compare = $resultat[0];
// we will be using $compare to see if this row
// matches one in $panier.. this needs to be changed
// appropriately. I don't have enough info to define it....
// this needs to be a unique field, or it should be
// it is going to be used like this: if($resultat[$i] == $panier[$j][0])
$result[ $compare ] = $resultat;
}
$hi = 0;
foreach( $panier as $index => $panier_row )
{
$compare = $panier_row[0];
if (isset($result[$compare]))
{
$H = 0;
// change $session to $_SESSION for your code...
$session['Panier']['Id'][$hi][$H] = $result[$compare][0];
$session['Panier']['CodeCours'][$hi][$H] = $result[$compare][1];
$session['Panier']['Titre'][$hi][$H] = $result[$compare][2];
$session['Panier']['Prealable'][$hi][$H] = $result[$compare][3];
$session['Panier']['NbHeure'][$hi][$H] = $result[$compare][4];
$session['Panier']['Session'][$hi][$H] = $result[$compare][5];
$session['Panier']['Credit'][$hi][$H] = $result[$compare][6];
$H++;
$hi++;
}
}
}
my results show $session['Panier']['Credit'] as having three things for 1, 2, 3 but not 4 or 5 because they don't match $panier.
what is in $session at the end of all that:
array (
'Panier' =>
array (
'Id' =>
array (
0 =>
array (
0 => 1,
),
1 =>
array (
0 => 2,
),
2 =>
array (
0 => 3,
),
),
'CodeCours' =>
array (
0 =>
array (
0 => 'one',
),
1 =>
array (
0 => 'two',
),
2 =>
array (
0 => 'three',
),
),
'Titre' =>
array (
0 =>
array (
0 => 'Titre1',
),
1 =>
array (
0 => 'Titre2',
),
2 =>
array (
0 => 'Titre3',
),
),
'Prealable' =>
array (
0 =>
array (
0 => 'Prealable1',
),
1 =>
array (
0 => 'Prealable2',
),
2 =>
array (
0 => 'Prealable3',
),
),
'NbHeure' =>
array (
0 =>
array (
0 => 'NbHeure1',
),
1 =>
array (
0 => 'NbHeure2',
),
2 =>
array (
0 => 'NbHeure3',
),
),
'Session' =>
array (
0 =>
array (
0 => 'Session1',
),
1 =>
array (
0 => 'Session2',
),
2 =>
array (
0 => 'Session3',
),
),
'Credit' =>
array (
0 =>
array (
0 => 'Credit1',
),
1 =>
array (
0 => 'Credit2',
),
2 =>
array (
0 => 'Credit3',
),
),
),
)
personally, though... you should use mysql_fetch_assoc and do it like this:
$session = array();
$panier = array(array(1,'one'),array(2,'two'),array(3,'three'),);
$req = array(
array('id'=>1,'var'=>'one','Titre'=>'Titre1','Prealable'=>'Prealable1','NbHeure'=>'NbHeure1','Session'=>'Session1','Credit'=>'Credit1'),
array('id'=>2,'var'=>'two','Titre'=>'Titre2','Prealable'=>'Prealable2','NbHeure'=>'NbHeure2','Session'=>'Session2','Credit'=>'Credit2'),
array('id'=>3,'var'=>'thr','Titre'=>'Titre3','Prealable'=>'Prealable3','NbHeure'=>'NbHeure3','Session'=>'Session3','Credit'=>'Credit3'),
array('id'=>4,'var'=>'fou','Titre'=>'Titre4','Prealable'=>'Prealable4','NbHeure'=>'NbHeure4','Session'=>'Session4','Credit'=>'Credit4'),
array('id'=>5,'var'=>'fiv','Titre'=>'Titre5','Prealable'=>'Prealable5','NbHeure'=>'NbHeure5','Session'=>'Session5','Credit'=>'Credit5'),);
// $req = mysql_query("SELECT * FROM cours", $connection);
if ($req!==false)
{
foreach( $req as $i => $resultat ) // testing row, remove for real
// while( $resultat = mysql_fetch_assoc($req) ) // real row, uncomment for you
// mysql_fetch_assoc !!
{
$compare = $resultat['id'];
// we will be using $compare to see if this row
// matches one in $panier.. this needs to be changed
// appropriately. I don't have enough info to define it....
// this needs to be a unique field, or it should be
$result[ $compare ] = $resultat;
}
foreach( $panier as $index => $panier_row )
{
$compare = $panier_row[0];
if (isset($result[$compare]))
{
$session[] = $result[$compare];
}
}
}
and this is $session
array (
0 =>
array (
'id' => 1,
'var' => 'one',
'Titre' => 'Titre1',
'Prealable' => 'Prealable1',
'NbHeure' => 'NbHeure1',
'Session' => 'Session1',
'Credit' => 'Credit1',
),
1 =>
array (
'id' => 2,
'var' => 'two',
'Titre' => 'Titre2',
'Prealable' => 'Prealable2',
'NbHeure' => 'NbHeure2',
'Session' => 'Session2',
'Credit' => 'Credit2',
),
2 =>
array (
'id' => 3,
'var' => 'thr',
'Titre' => 'Titre3',
'Prealable' => 'Prealable3',
'NbHeure' => 'NbHeure3',
'Session' => 'Session3',
'Credit' => 'Credit3',
),
)