I want to sort arrays, but I can't? - php

I have a JSON file that I created, and I want to sort from the biggest price value.
JSON is like this:
[
{
"username": "elbugato",
"sold": 19,
"qmimi": 38.5
},
{
"username": "Pablo",
"sold": 12,
"qmimi": 42
},
{
"username": "Hqstuff",
"sold": 0,
"qmimi": "0"
},
{
"username": "matchspamm3rs",
"sold": 0,
"qmimi": "0"
},
{
"username": "Pachenko",
"sold": 1,
"qmimi": 1.1
},
I want to sort qmimi from the highest value
My php code is this.
$sellertop8json = json_decode(get_html('link'));
$i = 1;
sort($sellertop8json->qmimi, SORT_NUMERIC);
foreach($sellertop8json as $top8){
max($top8);
if (++$i == 8) break;
echo '<tr>
<td>'.$top8->username.'</td>
<td># '.$top8->sold.'</td>
<td>$ '.$top8->qmimi.'</td>
</tr>
';
}
but they aren't sorting from the biggest value
The results I get :
Look at "Pachenko", he is after a seller that has "0" Earned.
Thank You
Sorry for my bad English
P.S : JSON ISN'T RAW, I copied from some extension I am using on google chrome, so JSON it's not the problem.

You need to use usort and provide custom function comparing the field of the element:
usort($sellertop8json, function($a, $b) {
return $a->qmimi == $b->qmimi ? 0 :
$a->qmimi < $b->qmimi ? 1 : -1;
}
);
The comparison function must return 0 if the elements are equal, less than 0 if the first element is lower and greater than 0 if the second element is higher.
This may be a bit confusing as you're sorting from highest and therefore the swap of the sign in comparison - see the last part of comparison.

Related

sum availibilty of user in minute

I want to calcul the total availability of an user:
I store availibilty like this :
And I have history of availibilty cause user can change their availibilty so I need to make the sum with this.
signupDate to first UpdateDATE and after
updateDate[i] to updateDate[i+1]
and at the end
updateDate[i+n] to now;
and get for each duration in minute :
endHours - startHours
I got json like this :
availibility object are per week
{
"2022-12-20" (date when user have signup ): [
{
dayNumber : 2,
startHours:08:00,
endHours :10:00;
},
{
dayNumber : 3,
startHours:11:00,
endHours :16:00;
}
],
"2022-12-28" (date when user have update his availibilties): [
{
dayNumber : 2,
startHours:08:00,
endHours :10:00;
},
{
dayNumber : 3,
startHours:11:00,
endHours :16:00;
}
],
"2023-01-01" (date when user have update his availibilties): [
{
dayNumber : 5,
startHours:05:00,
endHours :10:00;
},
{
dayNumber : 7,
startHours:19:00,
endHours :22:00;
}
]
}
Whats I have start for the moment :
I have count number of weeks beetwen signupDate and now :
$number_of_week = Carbon::parse($user->signupDate)->diffInWeeks(Carbon::now());
Finaly I want to get total availibilty of the user
Thanks
After our chat, I think I got the full picture of the problem, so lets see if we can solve this together:
I'm not sure where the json comes from, so let's just assign it to a variable for now:
$jsonString = '
{
"2022 - 12 - 20": [
{
"dayNumber": 2,
"startHours": "08:00",
"endHours": "10:00"
},
{
"dayNumber": 3,
"startHours": "11:00",
"endHours": "16:00"
}
],
"2022 - 12 - 28": [
{
"dayNumber": 2,
"startHours": "08:00",
"endHours": "10:00"
},
{
"dayNumber": 3,
"startHours": "11:00",
"endHours": "16:00"
}
],
"2023 - 01 - 01": [
{
"dayNumber": 5,
"startHours": "05:00",
"endHours": "10:00"
},
{
"dayNumber": 7,
"startHours": "19:00",
"endHours": "22:00"
}
]
}
';
Then, we can run the code like so:
//I'm assuming that the json only contains availabilities for 1 user
//This creates an associated array out of your json
$assocArray = json_decode($jsonString, true);
$totalAvailabilityInMinutes = 0;
foreach($assocArray as $updatedAvailabilityAt => $availabilityArray) {
$availabilityOfDayInMinutes = 0;
foreach($availabilityArray as $availability) {
$explodedStart = explode(':', $availability['startHours']);
$explodedEnd = explode(':', $availability['endHours']);
//Perform calculation from my comment
$availabilityOfDayInMinutes = ($explodedEnd[0] * 60 + $explodedEnd[1]) - ($explodedStart[0] * 60 + $explodedStart[1]);
dump("Availability of day {$availability['dayNumber']}: $availabilityOfDayInMinutes");
$totalAvailabilityInMinutes += $availabilityOfDayInMinutes;
}
}
dump($totalAvailabilityInMinutes);
Please note that I used 2 variables to store the minutes, one per day, and one accumulating the days. You can pick which one is most applicable to you.
I've tested the code locally, it should work and provide correct numbers ;)
Edit:
So since you already have an array, not a json, you could skip this step:
$assocArray = json_decode($jsonString, true);

Sorting Minutes

im trying to sort soccer minutes, but is not sorting right, for example in soccer is very normal minutes be like "1,2,3,40+5...". Basically is saying 40 minutes + 5 minutes (45 minutes).
So in my records i a colllection like:
[
{
"id": 9876,
"minute": "90+30",
},
{
"id": 9874,
"minute": "90+10",
},
{
"id": 9873,
"minute": "105",
},
{
"id": 9873,
"minute": "90",
},
...
]
So to make it order the minutes right, i need to use explode on the string "minute", than make a array_sum, but in my code, it still doesnt order right, still in the 105 is above of "90+10".
Here is my code:
$timelines = SoccerTime::where('match_id',$id)
->orderBy('minute', 'desc')
->get();
$collection = collect($timelines);
$sorted = $collection->sortByDesc('minute');
$test = $sorted->values()->all();
//Here i begin the new Sort
$newSort = collect($test)->sort(function ($a, $b) {
return array_sum(explode("+",$a->minute)) - array_sum(explode("+",$b->minute));
});
return $newSort;
I think you should change a couple of field in your model. I'd use a minute field to store the actual minute (100 in cases like your "90+10" example) and another integer field period to indicate the "period", where:
- 1 for 1T
- 2 for 2T
- 3 for 1ET
- 4 for 2ET.
So your new way of sorting should be:
First by period (solving your problem of getting 90'+4' of 2T before 93' of 1ET) and then by minute (the actual sort).
It would be so much easier and it could also help you to do some other reporting queries.

How does this recursive code to find all permutations of a string work?

I am doing Project Euler problems. I am currently working on the circular primes problem
The number, 197, is called a circular prime because all rotations of the digits: 197, 971, and 719, are themselves prime.
There are thirteen such primes below 100: 2, 3, 5, 7, 11, 13, 17, 31, 37, 71, 73, 79, and 97.
How many circular primes are there below one million?
Although checking if something is primes was easy for me, I could not figure out how to get all the permutations of the numbers. After a good bit of searching for tips on an algorithm to do that, I came across a website which gave code for that in Java, which I adapted to PHP below. However, before proceeding with the problem, I would really like to understand what exactly the different bits of the code are doing, especially in the for loop. What I understand of it so far is that in the for loop, it is starting with an empty prefix and then looping through the string and adding a single element from the string to the prefix, until there is only one element left in the original string, at which point, it echoes it out. Am I understanding this correctly? If not, what am I missing?
<?php
getallcombos("","1234");
function getallcombos($prefix,$string){
if(strlen($string)==1){
echo $prefix.$string."<br>";
}
$array=str_split($string);
for($i=0;$i<strlen($string);$i++){
$newstr=substr($string,0,$i).substr($string,$i+1);
getallcombos($prefix.$array[$i],$newstr);
}
}
?>
The problem does not ask for permutations, but rotations. This is different. For all rotations, you can do a loop:
var number = "2031";
var rotations = [];
for (i = 0; i < number.length; ++i) {
number = number.substring(1)
+ number[0];
rotations.push(number);
}
console.log(rotations);
http://jsfiddle.net/T6Mur/
UPDATE
Specially for you:
function allRotArePrime(number) {
var int;
for (i = 0; i < number.length; ++i) {
int = parseInt(
number.substring(i) +
number.substring(0, i)
);
// if (!isPrime(int)) return false;
console.log(int);
}
//return true;
}
var num = 1927;
allRotArePrime(num.toString());
http://jsfiddle.net/T6Mur/3/
The if is your stopping condition. If string is only length 1 you only have one permutation.
the for loop is complex but it does something like this:
"" "1234" -> loop 4 times, giving:
"1", "234"
"2", "134"
"3", "124"
"4", "123"
Basically it moves one character from string to prefix, and it does all combinations to get all permutations.
Then it runs then next loop, which gives:
"12" "34"
"13" "24"
"14" "23"
"21" "34"
.. etc
Eventually you will get:
"123" "4" -> "1234"
"124" "3" -> "1243"
.. etc
As for you problem: note that it will be inefficient for numbers like 777 it will just give you 777 6 times. Also, you need rotations, not permutations. 197 should give 197,971,719 but not 179,791,917

How would I convert this array to usable javascript array?

I have php code that returns this from a database,
[
{
"Time": "2012-11-27 16:10:35",
"NumPlayers": "1"
},
{
"Time": "2012-11-27 16:24:55",
"NumPlayers": "1"
},
{
"Time": "2012-11-27 16:25:37",
"NumPlayers": "2"
},
{
"Time": "2012-11-27 16:29:33",
"NumPlayers": "2"
The times are MySQL timestamps. I need to get it into this format to use with Highcharts javascript charting.
data: [
[Date.UTC(1970, 9, 9), 0 ],
[Date.UTC(1970, 9, 14), 0.15],
[Date.UTC(1970, 10, 28), 0.35],
[Date.UTC(1970, 11, 12), 0.46],
I'm having trouble figuring out how to loop through the MySQL results and convert the timestamps to javascript Date.UTC objects. I need to place the NumPlayers value after the Date.UTC objects, and output it in the format below. I'm a PHP and javascript noob :\
It should look something like this:
data: [
[Date.UTC(2012, 11, 27, 16, 10, 35), 1],
[Date.UTC(2012, 11, 27, 16, 24, 55), 1],
[Date.UTC(2012, 11, 27, 16, 25, 37), 2],
[Date.UTC(2012, 11, 27, 16, 29, 33), 2],
You should realize that Date.UTC(2012, 11, 27, 16, 10, 35) simply returns the number of milliseconds since the epoch (1356624635000). Therefore, you can just convert your object into UNIX timestamps (times a 1000 since JS works with millisecond timestamps, but PHP works with seconds).
Sample Code
$data = '[{"Time": "2012-11-27 16:10:35", "NumPlayers": "1"}, {"Time": "2012-11-27 16:24:55", "NumPlayers": "1"}]';
// Make sure date is parsed as UTC
date_default_timezone_set("UTC");
// Convert items into the desired format
$mapper = function($item) {
return array(strtotime($item->Time)*1000, $item->NumPlayers);
}
echo json_encode(array_map($mapper, json_decode($data)));
Output
[[1354032635000,"1"],[1354033495000,"1"]]
You seem to be getting straight JSON from your database, which you can always convert into an array:
$data = '[{"Time": "2012-11-27 16:10:35", "NumPlayers": "1"}, {"Time": "2012-11-27 16:24:55", "NumPlayers": "1"}]';
$arrayData = json_decode($data, true);
After which you can simply iterate through the array and print out the contents of the array in the JS format you need. Something like that:
echo 'data: [' . PHP_EOL;
foreach ($arrayData as $item) {
echo '[Date.UTC(';
$tmp = preg_split( '/(-| |\:)/', $item['Time'] );
echo implode(', ', $tmp);
echo '), ' . $item['NumPlayers'] . '],';
echo PHP_EOL;
}
echo PHP_EOL . '];';
You can split the time string into sections using /[^\d]+/g:
var finalData = [], numbers=/[^\d]+/g, item, dateParts, newDate;
for (var i=0, l=data.length; i<l; i++) {
item = data[i];
dateParts = item.Time.split(numbers);
newDate = Date.UTC.apply(Date, dateParts);
finalData.push([newDate, item.NumPlayers]);
}
See also: MDN's documentation on JavaScript regular expressions (/[^\d]/g is a regex).
The best way to provide data to Highcharts is getting data formated from database, so that you don't have to do it on client side.
To do it you just have to change your query to something like the following.
Backend
$query = "SELECT UNIX_TIMESTAMP(date) * 1000 AS 'date', value FROM ...";
Then to send the result to frontend:
echo json_encode($result);
Frontend
To get the result on frontend, this case using jQuery and assuming that url is your url:
$.getJSON(url, function(json) {
// decode json
var data = $.parseJSON(json);
// Then you just have to pass it to your series
});
Or better, store date values in UTC.
var php_data = [
{
"Time": "2012-11-27 16:10:35",
"NumPlayers": "1"
},
{
"Time": "2012-11-27 16:24:55",
"NumPlayers": "1"
}
];
var length = php_data.length;
hc_data = [];
for(var i = 0; i< length; i++){
php_date = new Date(php_data[i]["Time"]);
hc_data.push(
[
Date.UTC(
php_date.getFullYear(),
php_date.getMonth() + 1,
php_date.getDate()
),
php_data[i]["NumPlayers"]
]
);
}
// hc_data is your Array

PHP reading invalid json with json_decode();

I have invalid external json data, without double quotes around names.
Example:
{
data: [
{
idx: 0,
id: "0",
url: "http://247wallst.com/",
a: [
{
t: "Title",
u: "http://247wallst.com/2012/07/30/",
sp: "About"
}
],
doc_id: "9386093612452939480"
},
{
idx: 1,
id: "-1"
}
],
results_per_page: 10,
total_number_of_news: 76,
news_per_month: [20, 0, 8, 1, 1, 2, 0, 2, 1, 0, 0, 1, 1, 0, 5, 1, 1, 1, 0, 2, 5, 16, 7, 1],
result_start_num: 2,
result_end_num: 2,
result_total_articles: 76
}
As you see a lot of names like data,idx,id,url and others are not double quoted, so this makes this json invalid.
How can I make this external json valid? I already tried str_replace, replacing '{' to '{"' and ':' to '":' adding double quotes around unquoted names, but this messes up some already double quoted variables.
How can I make this json valid so I can read this data with PHP json_decode? I'm not very familiar with preg_replace..
Valid json will look like:
{
"data": [
{
"idx": 0,
"id": "0",
"url": "http://247wallst.com/",
"a": [
{
"t": "Title",
"u": "http://247wallst.com/2012/07/30/",
"sp": "About"
}
],
"doc_id": "9386093612452939480"
},
{
"idx": 1,
"id": "-1"
}
],
"results_per_page": 10,
"total_number_of_news": 76,
"news_per_month": [20, 0, 8, 1, 1, 2, 0, 2, 1, 0, 0, 1, 1, 0, 5, 1, 1, 1, 0, 2, 5, 16, 7, 1],
"result_start_num": 2,
"result_end_num": 2,
"result_total_articles": 76
}
Please suggest me some php preg_replace function.
Data source:
http://www.google.com/finance/company_news?q=aapl&output=json&start=1&num=1
With preg_replace you can do:
json_decode(preg_replace('#(?<pre>\{|\[|,)\s*(?<key>(?:\w|_)+)\s*:#im', '$1"$2":', $in));
Since the above example won't work with real data (the battle plans seldom survive first contact with the enemy) heres my second take:
$infile = 'http://www.google.com/finance/company_news?q=aapl&output=json&start=1&num=1';
// first, get rid of the \x26 and other encoded bytes.
$in = preg_replace_callback('/\\\x([0-9A-F]{2})/i',
function($match){
return chr(intval($match[1], 16));
}, file_get_contents($infile));
$out = $in;
// find key candidates
preg_match_all('#(?<=\{|\[|,)\s*(?<key>(?:\w|_)+?)\s*:#im', $in, $m, PREG_OFFSET_CAPTURE);
$replaces_so_far = 0;
// check each candidate if its in a quoted string or not
foreach ($m['key'] as $match) {
$position = $match[1] + ($replaces_so_far * 2); // every time you expand one key, offsets need to be shifted with 2 (for the two " chars)
$key = $match[0];
$quotes_before = preg_match_all('/(?<!\\\)"/', substr($out, 0, $position), $m2);
if ($quotes_before % 2) { // not even number of not-escaped quotes, we are in quotes, ignore candidate
continue;
}
$out = substr_replace($out, '"'.$key.'"', $position, strlen($key));
++$replaces_so_far;
}
var_export(json_decode($out, true));
But since google offers this data in RSS feed, i would recommend you to use that one if it works for your usecase, this is just for fun (-:
The JSON feeds from Google always seem to be plagued with problems- formatted incorrectly in some way shape or form. If you switch the feed to RSS you can easily convert it to an array or JSON from the array.
<?php
$contents = file_get_contents('http://www.google.com/finance/company_news?q=aapl&output=rss&start=1&num=1');
// Convert the RSS to an array (probably just use this)
$arr = simplexml_load_string($contents);
// Or if you specifically want JSON
$json = json_encode($arr);
// And back to an array
print_r(json_decode($json));

Categories