I need to get the minimum value of this array.
I am using array_maps and running it with for and can't find what I want.
$des['PICO']['new'] = 98;
$des['PICO']['old'] = 100;
$des['ALTO']['new'] = 101;
$des['ALTO']['old'] = 110;
$des['BAI']['new'] = 96;
$des['BAI']['old'] = 102;
$min_new = null;
$min_old = null;
$min_key = null;
foreach($des as $key => $value){
if($min_new < $value['new']){
$min_new = $value['new'];
$min_old = $value['old'];
$min_key = $key;
}
}
The main problem is that you are starting your min value at null. This will mean that none of the values are less than that. So start it at the highest int and only store the key value for use later...
$min_new = PHP_INT_MAX;
$min_key = null;
foreach($des as $key => $value){
if($min_new > $value['new']){
$min_new = $value['new'];
$min_key = $key;
}
}
print_r($des[$min_key]);
<?php
$des['PICO']['new'] = 98;
$des['PICO']['old'] = 100;
$des['ALTO']['new'] = 101;
$des['ALTO']['old'] = 110;
$des['BAI']['new'] = 96;
$des['BAI']['old'] = 102;
$min_new = PHP_INT_MAX;
$min_old = PHP_INT_MAX;
$min_key = PHP_INT_MAX;
foreach($des as $key => $value){
if($min_new > $value['new']){
$min_new = $value['new'];
}
if($min_old > $value['old']){
$min_old = $value['old'];
}
if($min_key > $min_new ){
$min_key = $min_new;
}
if($min_key > $min_old ){
$min_key = $min_old;
}
}
echo "n=". $min_new . " o=" . $min_old . " k=" . $min_key;
?>
or
foreach($des as $key => $value){
if($min_new > $value['new']){
$min_new = $value['new'];
$min_key = $key;
}
if($min_old > $value['old']){
$min_old = $value['old'];
$min_key = $key;
}
}
echo "n=". $min_new . " o=" . $min_old . " k=" . $min_key;
Output:
n=96 o=100 k=BAI
Related
I have table lids with under 430k entries.
How can I do SELECT query faster, optimized because now this query working under 5-7 minutes.
Heard something about Eloquent chunk in Laravel, but need clear PHP solution or with DB object.
Maybe with 'for' construction to process 100-1000 entries at a time, smthng like this.
Tried to do 'for' construction, but don't know how to do this optimized.
Be gentle with me pls :)
Want to know your opinion.
How can i upgrade it?
UPD: Did something like this
$count = $db->doQuery("SELECT count(*) FROM `lids`"); // db - my custom object with Database connection
$count = $count[0]['count(*)'];
$hundreds = $count / 100; // get 'for' counts
$start = 43; // id index starts from 43 in the table
$end = 142;
for ($index = 1; $index < $hundreds; $index++) {
$leads = [];
$leads = $db->doQuery("SELECT * FROM `lids` WHERE `id` BETWEEN " . $start . " AND " . $end . "");
// var_dump($leads);
// die();
if (empty($leads)) {
$start += 100;
$end += 100;
continue;
}
$uniques = [];
foreach ($leads as $lead) {
if (empty($lead['json_vars'])) continue;
$vars = preg_replace('/[\x00-\x1F\x80-\xFF]/', '', $lead['json_vars']); // hot fix for charset, from DB comes string in utf8mb4
$json = json_decode($vars, true);
if (!isset($json['ser']['HTTP_COOKIE']) || !str_contains($json['ser']['HTTP_COOKIE'], '_fbc')) continue;
$lead['json_vars'] = $json['ser']['HTTP_COOKIE'];
// check for unique values
if (!isset($uniques[$lead['id']]) || $uniques[$lead['id']]['phone'] != $lead['phone']) {
$uniques[$lead['id']] = $lead;
}
}
foreach ($uniques as $unique) {
$lid = Lid::create($unique);
}
$start += 100;
$end += 100;
// here i get residue of entries
if ($hundreds - $index < 1) {
$leads = $db->doQuery("SELECT * FROM `lids` WHERE `id` IN(" . ($count - $hundreds * 100) . ", " . $count . ") AND WHERE ");
foreach ($leads as $lead) {
$json = json_decode(preg_replace('/[\x00-\x1F\x80-\xFF]/', '', $lead['json_vars']), true);
if (!str_contains($json['ser']['HTTP_COOKIE'], '_fbc')) continue;
$lead['json_vars'] = $json['ser']['HTTP_COOKIE'];
$lid = Lid::create($lead);
}
}
}
Upd2:
$db = new Database();
$counter = 0;
$scriptStart = date('d.m.Y H:i:s', strtotime('now'));
$lastRemote = $db->lastId('lids');
$lastInner = Lid::all(['id'])->last();
$lastInner = $lastInner->id;
$count = $lastRemote - $lastInner;
if ($count < 0) {
echo 'no new objects, canceled';
return false;
}
$start = $lastInner + 1;
$end = $lastRemote;
$fewEntries = false;
if ($count < 500) {
$fewEntries = true;
$index = $lastInner;
$hundreds = $lastRemote;
} else {
$index = 1;
$hundreds = $count / 100;
$end = $start + 99;
}
if ($fewEntries) {
$leads = $db->itemsBetween('lids', 'id', [$start, $end]);
$uniques = [];
foreach ($leads as $lead) {
if (empty($lead['json_vars'])) continue;
$vars = preg_replace('/[\x00-\x1F\x80-\xFF]/', '', $lead['json_vars']);
$json = json_decode($vars, true);
if (!isset($json['ser']['HTTP_COOKIE']) || !str_contains($json['ser']['HTTP_COOKIE'], '_fbc')) continue;
$lead['json_vars'] = $json['ser']['HTTP_COOKIE'];
if (
!isset($uniques[$lead['id']]) ||
$uniques[$lead['id']]['phone'] != $lead['phone'] &&
$uniques[$lead['id']]['ip'] != $lead['ip'] &&
$uniques[$lead['id']]['request_link'] != $lead['request_link']
) {
$uniques[$lead['id']] = $lead;
}
}
foreach ($uniques as $unique) {
$lid = Lid::create($unique);
$counter++;
}
} else {
for ($index; $index < $hundreds; $index++) {
$leads = [];
$leads = $db->itemsBetween('lids', 'id', [$start, $end]);
// var_dump($leads);
// die();
$uniques = [];
foreach ($leads as $lead) {
if (empty($lead['json_vars'])) continue;
$vars = preg_replace('/[\x00-\x1F\x80-\xFF]/', '', $lead['json_vars']);
$json = json_decode($vars, true);
if (!isset($json['ser']['HTTP_COOKIE']) || !str_contains($json['ser']['HTTP_COOKIE'], '_fbc')) continue;
$lead['json_vars'] = $json['ser']['HTTP_COOKIE'];
if (
!isset($uniques[$lead['id']]) ||
$uniques[$lead['id']]['phone'] != $lead['phone'] &&
$uniques[$lead['id']]['ip'] != $lead['ip'] &&
$uniques[$lead['id']]['request_link'] != $lead['request_link']
) {
$uniques[$lead['id']] = $lead;
}
}
foreach ($uniques as $unique) {
$lid = Lid::create($unique);
$counter++;
}
$start += 100;
$end += 100;
}
}
$scriptEnd = date('d.m.Y H:i:s', strtotime('now'));
echo 'added in table: ' . $counter . PHP_EOL;
echo 'started at: ' . $scriptStart . PHP_EOL;
echo 'ended at: ' . $scriptEnd . PHP_EOL;
Resolved my problem with optimization of my trash code XD
$db = new Database();
$counter = 0;
$scriptStart = date('d.m.Y H:i:s', strtotime('now'));
$lastRemote = $db->lastId('lids');
$lastInner = Lid::all(['id'])->last();
$lastInner = $lastInner->id;
$count = $lastRemote - $lastInner;
if ($count < 0) {
echo 'no new objects, canceled';
return false;
}
$start = $lastInner + 1;
$end = $lastRemote;
$fewEntries = false;
if ($count < 500) {
$fewEntries = true;
$index = $lastInner;
$hundreds = $lastRemote;
} else {
$index = 1;
$hundreds = $count / 100;
$end = $start + 99;
}
if ($fewEntries) {
$leads = $db->itemsBetween('lids', 'id', [$start, $end]);
$uniques = [];
foreach ($leads as $lead) {
if (empty($lead['json_vars'])) continue;
$vars = preg_replace('/[\x00-\x1F\x80-\xFF]/', '', $lead['json_vars']);
$json = json_decode($vars, true);
if (!isset($json['ser']['HTTP_COOKIE']) || !str_contains($json['ser']['HTTP_COOKIE'], '_fbc')) continue;
$lead['json_vars'] = $json['ser']['HTTP_COOKIE'];
if (
!isset($uniques[$lead['id']]) ||
$uniques[$lead['id']]['phone'] != $lead['phone'] &&
$uniques[$lead['id']]['ip'] != $lead['ip'] &&
$uniques[$lead['id']]['request_link'] != $lead['request_link']
) {
$uniques[$lead['id']] = $lead;
}
}
foreach ($uniques as $unique) {
$lid = Lid::create($unique);
$counter++;
}
} else {
for ($index; $index < $hundreds; $index++) {
$leads = [];
$leads = $db->itemsBetween('lids', 'id', [$start, $end]);
// var_dump($leads);
// die();
$uniques = [];
foreach ($leads as $lead) {
if (empty($lead['json_vars'])) continue;
$vars = preg_replace('/[\x00-\x1F\x80-\xFF]/', '', $lead['json_vars']);
$json = json_decode($vars, true);
if (!isset($json['ser']['HTTP_COOKIE']) || !str_contains($json['ser']['HTTP_COOKIE'], '_fbc')) continue;
$lead['json_vars'] = $json['ser']['HTTP_COOKIE'];
if (
!isset($uniques[$lead['id']]) ||
$uniques[$lead['id']]['phone'] != $lead['phone'] &&
$uniques[$lead['id']]['ip'] != $lead['ip'] &&
$uniques[$lead['id']]['request_link'] != $lead['request_link']
) {
$uniques[$lead['id']] = $lead;
}
}
foreach ($uniques as $unique) {
$lid = Lid::create($unique);
$counter++;
}
$start += 100;
$end += 100;
}
}
$scriptEnd = date('d.m.Y H:i:s', strtotime('now'));
echo 'added in table: ' . $counter . PHP_EOL;
echo 'started at: ' . $scriptStart . PHP_EOL;
echo 'ended at: ' . $scriptEnd . PHP_EOL;
I'm trying to code Conway look-and-say sequence in PHP.
Here is my code:
function look_and_say ($number) {
$arr = str_split($number . " ");
$target = $arr[0];
$count = 0;
$res = "";
foreach($arr as $num){
if($num == $target){
$count++;
}else{
$res .= $count . $target;
$count = 1;
$target = $num;
}
}
return $res;
}
As I run the function, look_and_say(9900) I am getting value I expected: 2920.
My question is for assigning $arr to be $arr = str_split($number) rather than $arr = str_split($number . " "), the result omits the very last element of the $arr and return 29.
Is it normal to add empty space at the end of the $arr foreach to examine the last element or is there any better way to practice this code - besides regex way.
There are 2 methods I was able to come up with.
1 is to add concatenate at the result after the loop too.
function look_and_say ($number) {
$arr = str_split($number);
$target = $arr[0];
$count = 0;
$res = "";
foreach($arr as $num){
if($num == $target){
$count++;
}else{
$res .= $count . $target;
$count = 1;
$target = $num;
}
}
$res .= $count . $target;
return $res;
}
And the 2nd one is to add another if clause inside the loop and determine the last iteration:
function look_and_say ($number) {
$arr = str_split($number);
$target = $arr[0];
$count = 0;
$res = "";
$i=0;
$total = count($arr);
foreach($arr as $num){
if($i == ($total-1))
{
$count++;
$res .= $count . $target;
}
elseif($num == $target){
$count++;
}else{
$res .= $count . $target;
$count = 1;
$target = $num;
}
$i++;
}
return $res;
}
I want to suggest you other way using two nested while loops:
<?php
function lookAndSay($number) {
$digits = str_split($number);
$result = '';
$i = 0;
while ($i < count($digits)) {
$lastDigit = $digits[$i];
$count = 0;
while ($i < count($digits) && $lastDigit === $digits[$i]) {
$i++;
$count++;
}
$result .= $count . $lastDigit;
}
return $result;
}
I need to mount an array_multisort with the values from one array.
I tryied to mount a string concated and call on the array_multidimensional like here:
function ordenar_matriz_ultima_posicion_por_distancia($matriz_up,$m_vehiculo_distancias){
$total_vehiculos=count($matriz_up[id_vehiculo]);
//resetear las keys de vehiculos para coger bien los kms y asignarlos
$a_vehiculo_distancia = array_values($m_vehiculo_distancias);
$ordenar = array();
foreach ($a_vehiculo_distancia as $key) {
$ordenar[] = $key;
}
sort($m_vehiculo_distancias);
$string= "";
$ultim_key = end(array_keys($matriz_up));
foreach ($matriz_up as $key => $valor) {
if ($key != $ultim_key) $string.= $matriz_up[$key].',';
else $string.= $matriz_up[$key];
$aaa = '$matriz_up[$key]';
}
echo $string;
echo "<br>";
array_multisort($ordenar, SORT_ASC, $string);
for($i=0;$i<$total_vehiculos;$i++){
$matriz_up['cercanos'][$i] = $m_vehiculo_distancias[$i];
echo $matriz_up['id_vehiculo'][$i]."<br>";
echo $matriz_up['fecha_gps'][$i]."<br>";
echo $matriz_up['id_tipo_posicion'][$i]."<br>";
echo $matriz_up['cercanos'][$i]."<br>";
echo $matriz_up['vaina'][$i]."<br>";
echo "------------<br>";
}
return $matriz_up;
}
$matriz_up['id_vehiculo'][0] = 9;
$matriz_up['fecha_gps'][0] = '2014';
$matriz_up['id_tipo_posicion'][0] = 11111;
$matriz_up['cercanos'][0] = 0;
$matriz_up['vaina'][0] = 12345;
$matriz_up['id_vehiculo'][1] = 3;
$matriz_up['fecha_gps'][1] = '2015';
$matriz_up['id_tipo_posicion'][1] = 22222;
$matriz_up['cercanos'][1] = 0;
$matriz_up['vaina'][1] = 5555;
$matriz_up['id_vehiculo'][2] = 1;
$matriz_up['fecha_gps'][2] = '2016';
$matriz_up['id_tipo_posicion'][2] = 33333;
$matriz_up['cercanos'][2] = 0;
$matriz_up['vaina'][2] = 988;
$matriz_up['id_vehiculo'][3] = 4;
$matriz_up['fecha_gps'][3] = '2017';
$matriz_up['id_tipo_posicion'][3] = 44444;
$matriz_up['cercanos'][3] = 0;
$matriz_up['vaina'][3] = 777;
$m_vehiculo_distancias[9] = 345;
$m_vehiculo_distancias[3] = 712;
$m_vehiculo_distancias[1] = 10;
$m_vehiculo_distancias[4] = 35;
ordenar_matriz_ultima_posicion_por_distancia($matriz_up,$m_vehiculo_distancias);
With this array_multisort works, but i need to take all the key without put manually..
array_multisort($ordenar, SORT_ASC, $matriz_up['id_vehiculo'], $matriz_up['fecha_gps'], $matriz_up['id_tipo_posicion'], $matriz_up['vaina'] );
Try this code:
<?php
$matriz_up = $m_vehiculo_distancias = array();
$matriz_up['id_vehiculo'][0] = 9;
$matriz_up['fecha_gps'][0] = '2014';
$matriz_up['id_tipo_posicion'][0] = 11111;
$matriz_up['cercanos'][0] = 0;
$matriz_up['vaina'][0] = 12345;
$matriz_up['id_vehiculo'][1] = 3;
$matriz_up['fecha_gps'][1] = '2015';
$matriz_up['id_tipo_posicion'][1] = 22222;
$matriz_up['cercanos'][1] = 0;
$matriz_up['vaina'][1] = 5555;
$matriz_up['id_vehiculo'][2] = 1;
$matriz_up['fecha_gps'][2] = '2016';
$matriz_up['id_tipo_posicion'][2] = 33333;
$matriz_up['cercanos'][2] = 0;
$matriz_up['vaina'][2] = 988;
$matriz_up['id_vehiculo'][3] = 4;
$matriz_up['fecha_gps'][3] = '2017';
$matriz_up['id_tipo_posicion'][3] = 44444;
$matriz_up['cercanos'][3] = 0;
$matriz_up['vaina'][3] = 777;
$m_vehiculo_distancias[9] = 345;
$m_vehiculo_distancias[3] = 712;
$m_vehiculo_distancias[1] = 10;
$m_vehiculo_distancias[4] = 35;
function sortArray($arrayToSortParam, $orderArray)
{
$result = array();
$arrayToSort = $arrayToSortParam;
$keys = array_keys($arrayToSort);
asort($orderArray, true);
$newSort = $cercanos = array();
foreach($orderArray as $key => $value)
{
$newSort[] = array_keys($arrayToSort['id_vehiculo'], $key)[0];
$cercanos[] = $orderArray[$key];
}
foreach($keys as $keyName)
{
uksort($arrayToSort[$keyName], function($key1, $key2) use ($newSort) {
return (array_search($key1, $newSort) > array_search($key2, $newSort));
});
}
$arrayToSort['cercanos'] = $cercanos;
//reset indexes
foreach($keys as $keyName)
{
$arrayToSort[$keyName] = array_values($arrayToSort[$keyName]);
}
return $arrayToSort;
}
echo '<pre>';
//print_r($matriz_up);
//print_r($m_vehiculo_distancias);
print_r(sortArray($matriz_up, $m_vehiculo_distancias)); //this is result
Working fiddle: CLICK!
I have an array with a list of domains sorted by domain extensions, like:
values[0] = "programming.ca";
values[1] = "Stackoverflow.ca";
values[2] = "question.com";
values[3] = "answers.com";
values[4] = "AASystems.com";
values[5] = "test.net";
values[6] = "hello.net";
values[7] = "apple.nl";
values[8] = "table.org";
values[9] = "demo.org";
How do I print this array, while automatically grouping it in groups with same domain extension and separated by the line break <br />, so the result will look like this?
programming.ca
Stackoverflow.ca
question.com
answers.com
AASystems.com
test.net
hello.net
apple.nl
table.org
demo.org
Try this.
$ext = "";
for($i = 0; $i < count($values); $i++) {
$parts = explode('.', $values[$i]);
$e = $parts[count($parts) - 1];
if(strcmp($parts[count($parts) - 1], $ext) != 0) {
$ext = $e;
echo '<br/>';
}
echo $values[$i].'<br/>';
}
try this if domain names are in order of domain extensions,
$values[0] = "programming.ca";
$values[1] = "Stackoverflow.ca";
$values[2] = "question.com";
$values[3] = "answers.com";
$values[4] = "AASystems.com";
$values[5] = "test.net";
$values[6] = "hello.net";
$values[7] = "apple.nl";
$values[8] = "table.org";
$values[9] = "demo.org";
$prev_ext = "";
foreach($values as $domain_name)
{
$arr_temp = explode(".", $domain_name);
$domain_ext = $arr_temp[1];
if($prev_ext!=$domain_ext)
{
echo '<br/></br/><br/>';
}
echo $domain_name."<br/>";
$prev_ext = $domain_ext;
}
UPDATE : 2
try this if domain names are not in order of their extensions
$values[0] = "programming.ca";
$values[1] = "AASystems.com";
$values[2] = "demo.org";
$values[3] = "answers.com";
$values[4] = "Stackoverflow.ca";
$values[5] = "test.net";
$values[6] = "hello.net";
$values[7] = "apple.nl";
$values[8] = "table.org";
$values[9] = "question.com";
$arr_domains = array();
foreach($values as $domain_name)
{
$arr_temp = explode(".", $domain_name);
$domain_ext = $arr_temp[1];
$arr_domains[$domain_ext][] = $domain_name;
}
foreach($arr_domains as $ext=>$arr_name)
{
echo "<br/><br/><b>".$ext."</b><br/>";
foreach($arr_name as $name)
{
echo $name."<br/>";
}
}
I edited to hopefully make naming clearer. Basically, explode each domain to get name.extension, then store each name in a dictionary of (extension,domainArray) pairs, then foreach entry in the dictionary, grab the domainArray, then foreach name in the domainArray, echo out the domain name . extension, then a line break, then another line break for every dictionary entry.
<?php
$values[0] = "programming.ca";
$values[1] = "Stackoverflow.ca";
$values[2] = "question.com";
$values[3] = "answers.com";
$values[4] = "AASystems.com";
$values[5] = "test.net";
$values[6] = "hello.net";
$values[7] = "apple.nl";
$values[8] = "table.org";
$values[9] = "demo.org";
$domainsList = [];
foreach ($values as $val) {
$valArr = explode(".", $val);
$name = $valArr[0];
$extension = $valArr[1];
if (isset($domainsList[$extension])) {
$domainsList[$extension][] = $name;
} else {
$domainsList[$extension] = [$name];
}
}
foreach ($domainsList as $extension => $domains) {
foreach ($domains as $domain) {
echo $domain . "." . $extension . "<br />";
}
echo "<br />";
}
Try this code.
$domian = array(
"programming.ca",
"Stackoverflow.ca",
"question.com",
"answers.com",
"AASystems.com",
"test.net",
"hello.net",
"apple.nl",
"table.org",
"demo.org");
$result;
foreach ($domian as $value) {
$arr = explode('.', $value);
$result[$arr[1]][] = $value;
}
print_r($result);
I am trying to save an object with a variable amount of "cols". The number of cols is equal to the number of headers. This is how the code looked before:
if(isset($_POST['submit'])){
$sub = new Sub();
$sub->product_id = $_POST['product_id'];
$sub->col1 = $_POST['col1'];
$sub->col2 = $_POST['col2'];
$sub->col3 = $_POST['col3'];
$sub->col4 = $_POST['col4'];
$sub->col5 = $_POST['col5'];
$sub->col6 = $_POST['col6'];
$sub->col7 = $_POST['col7'];
$sub->col8 = $_POST['col8'];
$sub->col9 = $_POST['col9'];
$sub->col10 = $_POST['col10'];
$sub->col11 = $_POST['col11'];
$sub->col12 = $_POST['col12'];
$sub->col13 = $_POST['col13'];
$sub->col14 = $_POST['col14'];
$sub->col15 = $_POST['col15'];
This is how I want it to look:
if(isset($_POST['submit'])){
$sub = new Sub();
$sub->product_id = $_POST['product_id'];
$i = 0;
foreach($headers as $header){
$i++ ;
$sub->col.$i = $_POST['col'.$i];
}
How do I pass the variable $i into the object's attributes? $sub->(col.$i) ? $sub->(col{$i}) ? Please help me figure this out =) Thank you
Try this:
$sub = new Sub();
$sub->product_id = $_POST['product_id'];
for($i = 1; $i <= count($headers); ++$i)
$sub->{'col' . $i} = $_POST['col' . $i];
But, this is really not the way that the columns should be stored in the Sub object, you should use an array:
$sub->columns = array();
for($i = 1; $i <= count($headers); ++$i) {
$sub->columns[] = $_POST['col' . $i];
}
You have to use {} :
$sub->{'col' . $i} = ...
$field = "col$i";
$sub->$field = "whatver"
I'd prefer a setter method.
class Sub {
public function set($attribute, $value) {
$this->$attribute = $value;
}
}
Now you can do:
foreach($_POST as $key => $value) {
$sub->set($key, $value)
}
Or without the loose coupling:
$i = 1;
while($value = $_POST['col' . $i]) {
$sub->set('col' . $i, $value);
$i++;
}