PHP - Get timestamp from filename and sort in array - php

I have an example array with filenames:
$test_array = array (
'video-start-1537482914-stop-1537483670.zip',
'video-start-1537533156-stop-1537534299.zip',
'video-start-1537534300-stop-1537534630.zip',
'video-start-1537090052-stop-1537091001.zip'
);
I want to get start timestamp from each file and then sort them in array. I tried with preg_match but it only works for strings, not arrays. How can i achieve that?

public function testSort()
{
$test_array = array (
'video-start-1537482914-stop-1537483670.zip',
'video-start-1537533156-stop-1537534299.zip',
'video-start-1537534300-stop-1537534630.zip',
'video-start-1537090052-stop-1537091001.zip'
);
usort($test_array, function($a, $b) {
return ((int)explode('-',$a)[2] < (int)explode('-',$b)[2]) ? -1 : 1;
});
foreach($test_array as &$line) {
echo $line . PHP_EOL;
}
}

Try this:
<?php
$test_array = array(
'video-start-1537482914-stop-1537483670.zip',
'video-start-1537533156-stop-1537534299.zip',
'video-start-1537534300-stop-1537534630.zip',
'video-start-1537090052-stop-1537091001.zip'
);
foreach ($test_array as $item){
preg_match('/video-start-(.*?)-stop-/', $item, $match);
$timespan[] = $match[1];
}
//sorts an associative array in ascending order.
asort($timespan);
var_dump($timespan);
?>
Output start timestamp:
array (size=4)
3 => string '1537090052' (length=10)
0 => string '1537482914' (length=10)
1 => string '1537533156' (length=10)
2 => string '1537534300' (length=10)

Related

How to match string to an Array to get the value?

I have an array with corresponding value.
Array
(
[0] => BBsma=200
[1] => SMAperiod=300
[2] => SMA1=400
[3] => SMA2=500
[4] => EMAperiod=300
[5] => EMA1=24
[6] => EMA2=8
)
Now I want to match a certain string like for example BBsma that should return 200. Any help?
Got the array using these codes.
$txt = file_get_contents('INDICATORS.txt');
$rows = explode("\n", $txt);
array_shift($rows);
INDICATORS.txt content
BBperiod=100
BBsma=200
SMAperiod=300
SMA1=400
SMA2=500
EMAperiod=300
EMA1=24
EMA2=8
After you explode your text to the lines use this code:
for($i=0;$i<sizeof($rows);$i++)
{
$temp=explode("=",$rows[$i]);
if(sizeof($temp)==2)
{
$arr[$temp[0]]=$temp[1];
}
}
You will have named array in $arr
if you want to cast second part to int, you just change 6-line to this:
$arr[$temp[0]]=intval($temp[1]);
You could iterate over every line of your array and find the value with a regular match.
Code:
$txt = file_get_contents('INDICATORS.txt');
$rows = explode("\n", $txt);
/*
$rows = [
"BBsma=200",
"SMAperiod=300",
"SMA1=400",
"SMA2=500",
"EMAperiod=300",
"EMA1=24",
"EMA2=8",
];
*/
foreach ($rows as $k=>$v) {
if (preg_match("/(BBsma|SMAperiod|EMAperiod)=([0-9]+)/", $v, $matches)) {
echo "found value " . $matches[2] . " for entry " . $matches[1] . " in line " . $k . PHP_EOL;
}
}
Output:
found value 200 for entry BBsma in line 0
found value 300 for entry SMAperiod in line 1
found value 300 for entry EMAperiod in line 4
You can explode by new line as PHP_EOL like this
$col = "BBsma";
$val = "";
foreach(explode(PHP_EOL,$str) as $row){
$cols = explode("=",$row);
if(trim($cols[0]) == $col){
$val = $cols[1];
break;
}
}
echo "Value $col is : $val";
Live Demo
If your going to use the array a few times, it may be easier to read the file into an associative array in the first place...
$rows = [];
$file = "INDICATORS.txt";
$data = file($file, FILE_IGNORE_NEW_LINES);
foreach ( $data as $item ) {
$row = explode("=", $item);
$rows [$row[0]] = $row[1];
}
echo "EMA1 =".$rows['EMA1'];
This doesn't do the array_shift() but not sure why it's used, but easy to add back in.
This outputs...
EMA1 =24
I think that using array filter answers your question the best. It returns an array of strings with status code 200. If you wanted to have better control later on and sort / search through codes. I would recommend using array_walk to create some sort of multi dimensional array. Either solution will work.
<?php
$arr = [
"BBsma=200",
"SMAperiod=300",
"SMA1=400",
"SMA2=500",
"EMAperiod=300",
"EMA1=24",
"EMA2=8",
];
$filtered = array_filter($arr,"filter");
function filter($element) {
return strpos($element,"=200");
}
var_dump($filtered); // Returns array with all matching =200 codes: BBSMA=200
Output:
array (size=1)
0 => string 'BBsma=200' (length=9)
Should you want to do more I would recommend doing something like this:
///////// WALK The array for better control / manipulation
$walked = [];
array_walk($arr, function($item, $key) use (&$walked) {
list($key,$value) = explode("=", $item);
$walked[$key] = $value;
});
var_dump($walked);
This is going to give you an array with the parameter as the key and status code as it's value. I originally posted array_map but quickly realized array walk was a cleaner solution.
array (size=7)
'BBsma' => string '200' (length=3)
'SMAperiod' => string '300' (length=3)
'SMA1' => string '400' (length=3)
'SMA2' => string '500' (length=3)
'EMAperiod' => string '300' (length=3)
'EMA1' => string '24' (length=2)
'EMA2' => string '8' (length=1)
Working with the array becomes a lot easier this way:
echo $walked['BBsma']; // 200
$anything = array("BBsma"=>"200", "SMAperiod"=>"300", "SMA1"=>"400");
echo "the value is " . $anything['BBsma'];
This will return 200

extract only duplicate value from multidimensional array in php

I have array like this
$non_unique_zip
[0]->[0]91390
[1]ca
[2]1
[1]->[0]91391
[1]ca
[2]1
[2]->[0]91392
[1]ca
[2]1
[3]->[0]91390
[1]ca
[2]2
[4]->[0]91394
[1]ca
[2]2
so basically array has elements where arra[n][0] is zipcode and array[n][2] is buyer_id.
now out of this, i just want the zipcodes which have multiple buyers. so the only thing I want to extract is
[0]->[0]91390
[1]ca
since 91390 is the only zipcode which has buyer as 1 and 2.
I tried
$result = array();
$first = $non_unique_zip[0];
for($i=0; $i<count($non_unique_zip); $i++){
$result = array_intersect ($first, $non_unique_zip[$i]);
$first = $result;
}
but it just gives error undefined offset.
Any help will be appreciated.
If you call $records your starting array, here is a way to get the zips with 3 lines of code:
//array whose keys are zips, and values are # of occurances
$zips = array_count_values(array_column($records,0));
//filter keeps only zips which occur more than once.
$zips = array_filter($zips,function($n){return $n>1;});
//if you only need the zips, you're done! they are the keys
$zips = array_keys($zips);
Live demo
Use an array that keeps track of the zip codes that have already been encountered before. Then when you get a zip that's in that array, you know it's a duplicate.
$zips = array();
$result = array();
foreach ($non_unique_zip as $e) {
$code = $e[0];
if (isset($zips[$code])) { // duplicate, so add to $result
$result[$code] = array($code, $e[1]);
} else {
$zips[$code] = true; // first time, add it to $zips
}
}
Use array_walk like so:
<?php
$non_unique_zip = [
[91390, "ca"],
[91391, "ca"],
[91392, "ca"],
[91390, "ca"],
[91394, "ca"],
];
$unique_zip = [];
$duplicates = [];
array_walk($non_unique_zip, function($data) use(&$unique_zip, &$duplicates){
if(!in_array($data, $unique_zip)){
$unique_zip[] = $data;
}else{
$duplicates[] = $data;
}
});
var_dump( $duplicates );
// PRODUCES::
array (size=1)
0 =>
array (size=2)
0 => int 91390
1 => string 'ca' (length=2)
var_dump( $unique_zip );
// PRODUCES::
array (size=4)
0 =>
array (size=2)
0 => int 91390
1 => string 'ca' (length=2)
1 =>
array (size=2)
0 => int 91391
1 => string 'ca' (length=2)
2 =>
array (size=2)
0 => int 91392
1 => string 'ca' (length=2)
3 =>
array (size=2)
0 => int 91394
1 => string 'ca' (length=2)

what should i do to get array like this in php?

I have one array as below :
Array
(
[Sep] => Array
(
[Support Help Desk] => 24.67
[Development] => 7.74
[Consulting Services] => 4.04
)
[Oct] => Array
(
[Support Help Desk] => 14.38
[Business Activity] => 1.92
[Maintenance Tasks] => 1.00
[Development] => 2.11
)
)
and i want array like this :
Array
(
[Support Help Desk] => 24.67,14.38
[Development] => 7.74,2.11
[Consulting Services] => 4.04,0
[Business Activity] => 0,1.92
[Maintenance Tasks] => 0,1.00
)
I am using php with zend framework.
But i don't know what method should i use to get array like this ?
can anyone please guide me ?
-
Thanks in advance.
Third time lucky! I missed out on some subtleties in the question originally. Try the following code - it's a bit loopy but it should work for you.
I am assuming that your original array is called $data.
// first we need to 'normalise' or fill in the blanks in the contents of the sub array
// get a unique list of all the keys shared - doing it manually here
$keys = ['Support Help Desk', 'Business Activity', 'Maintenance Tasks', 'Development', 'Consulting Services'];
// create a default array with $keys, assigning 0 as the value of each
$default = array_fill_keys($keys, 0);
// next fill in the blanks...
// get the diff (missing keys) between the current element and the default array
// merge the missing key/value pairs
array_walk($data, function(&$month, $key, $default) {
$diff = array_diff_key($default, $month);
$month = array_merge($diff, $month);
}, $default);
// now the array is normalised
// flatten the array... where there are duplicate values for a key, and
// there will be in all cases now including default values
// a sub array is created
$merged = call_user_func_array('array_merge_recursive', $data);
// finally loop over the merged array
// and implode each array of values into a comma separated list
foreach ($merged as &$element) {
if (is_array($element)) {
$element = implode(', ', $element);
}
}
// done :)
var_dump($merged);
Yields:
array (size=5)
'Business Activity' => string '0, 1.92' (length=7)
'Maintenance Tasks' => string '0, 1' (length=4)
'Support Help Desk' => string '24.67, 14.38' (length=12)
'Development' => string '7.74, 2.11' (length=10)
'Consulting Services' => &string '4.04, 0' (length=7)
Hope this helps :)
EDIT
Live example at eval.in
Let's say your array is stored in $main_arr and result array is $result_arr.
$result_arr = array();
foreach ($main_arr as $month) {
foreach ($month as $key => $val) {
if (!isset($result_arr[$key])) {
$result_arr[$key] = array($val);
} else {
array_push($result_arr[$key], $val);
}
}
}
foreach ($result_arr as $key => $val) {
$result_arr[$key] = implode(', ', $val);
}
print_r($result_arr); //Final output.

php similar_text function on two arrays

I have two large arrays of scraped product names and prices similar to the following:
$one=array('grape'=>'0.40','apple'=>'1.20','banana'=>'1.80','lemon'=>'10.43');
$two=array('grappe'=>'1.20','kiwi'=>'7.54','banaana'=>'3.20','aubergine'=>'2.32');
I am attempting to iterate over the arrays using the similar_text function to return the keys that match eachother closely. For example i would like to extract the values of 'grappe'=>'1.20' and 'banaana'=>'3.20' from the above example.
I am unsure how to reference the arrays and pass them to the similar_text function as this function only accepts string data. I presume i will need to correctly reference the arrays using a foreach loop and use an if statement in conjunction with the similar_text function to specify the desired percentage of similarity between the two matches.
For example (within the foreach loop):
if ($result[] = (similar_text( $one, $two)) > 80) {
var_dump($result[]);
}
similar_text( $one, $two) Returns the number of matching chars in both strings so To get percentage you should run similar_text($one, $two, $percent); insted
Example
$one = array('grape' => '0.40','apple' => '1.20','banana' => '1.80','lemon' => '10.43');
$two = array('grappe' => '1.20','kiwi' => '7.54','banaana' => '3.20','aubergine' => '2.32');
$result = array();
foreach ( $one as $key => $value ) {
foreach ( $two as $twoKey => $twoValue ) {
similar_text($key, $twoKey, $percent);
if ($percent > 80) {
$result[$key] = array($value,$twoValue);
}
}
}
var_dump($result);
Output
array
'grape' =>
array
0 => string '0.40' (length=4)
1 => string '1.20' (length=4)
'banana' =>
array
0 => string '1.80' (length=4)
1 => string '3.20' (length=4)

PHP: Sorting arrays with values like -1- and -10-

I have a function that gets filenames from a directory, and then puts them in an array. All the filenames start with a code, as an example: -0-filename.php, -1-filename.php, -2-filename.php and -10-filename.php.
After some steps, the filenames are echoed out. The process looks like this:
rsort( $archiveArray );
$amount = count( $archiveArray );
$i = 0;
while( $i <= $amount )
{
echo $archiveArray[$i];
$i++;
}
Anyways. The problem is; when I get 10 files in the directory, and try to do the echoing process above, I get the names in a wrong order. - It's supposed to be :
-10-filename.php
-9-filename.php
-8-filename.php
...
-1-filename.php
-0-filename.php
But instead, I get
-9-filename.php
-8-filename.php
...
-10-filename.php
-1-filename.php
-0-filename.php
What's the quickest and easiest way to fix this?
EDIT:
If it wasn't obvious, the filenames are not always identical, even when not including the codes. The are always in this format: -number-randomtext.php, where number is always one higher than the last one, and randomtext can really be anything.
rsort has an optional second parameter called sort_flags. use SORT_NATURAL to do a "natural sort".
rsort($archiveArray, SORT_NATURAL);
Using rsort with SORT_NATURAL works if you're running PHP 5.4. If you're not, however:
natsort( $archiveArray );
$archiveArray = array_reverse( $archiveArray );
...will do the same thing. Just use natsort to do the natural order sorting, then reverse the array.
Test code (PHP 5.3.3):
php > $array = array( '-1-blah', '-2-foo', '-12-boo', '-11-yaay', '-3-bar' );
php > natsort( $array );
php > print_r( $array );
Array
(
[0] => -1-blah
[1] => -2-foo
[4] => -3-bar
[3] => -11-yaay
[2] => -12-boo
)
php > $array = array_reverse( $array );
php > print_r( $array );
Array
(
[0] => -12-boo
[1] => -11-yaay
[2] => -3-bar
[3] => -2-foo
[4] => -1-blah
)
php >
Another way to do this is usort, and write your own sorting criteria.
I used regular expressions to parse the numeric value from the string, as follows:
$files = array(
'-0-filename.php',
'-1-filename.php',
'-2-filename.php',
'-3-filename.php',
'-4-filename.php',
'-5-filename.php',
'-6-filename.php',
'-7-filename.php',
'-8-filename.php',
'-9-filename.php',
'-10-filename.php',
'-11-filename.php',
);
usort($files, 'CustomFileSequence');
var_dump($files);
function CustomFileSequence($a, $b)
{
$pattern = '/^\\-([0-9]*)\\-/';
preg_match($pattern, $a, $matches);
$a_val = $matches[1];
preg_match($pattern, $b, $matches);
$b_val = $matches[1];
if ($a_val < $b_val)
return 1;
if ($a_val > $b_val)
return -1;
if ($a_val == $b_val)
return 0;
}
Output is:
array
0 => string '-11-filename.php' (length=16)
1 => string '-10-filename.php' (length=16)
2 => string '-9-filename.php' (length=15)
3 => string '-8-filename.php' (length=15)
4 => string '-7-filename.php' (length=15)
5 => string '-6-filename.php' (length=15)
6 => string '-5-filename.php' (length=15)
7 => string '-4-filename.php' (length=15)
8 => string '-3-filename.php' (length=15)
9 => string '-2-filename.php' (length=15)
10 => string '-1-filename.php' (length=15)
11 => string '-0-filename.php' (length=15)
You need to convert the number to an int value. Right now it's being interpreted as a string. You can just do something like this:
$names = // your array of file names.
$sorted = // the sorted version names.
for($i = 0; $i < count($arr); $i++) {
$sorted[substr($names[$i], 1, strpos($names[$i], '-', 2))] = $names[$i];
}
print_r($sorted);
Basically, you take the name from $names, give it an index in the sorted array based on the number between the two -s, and add it to $sorted.
I used usort() to do this:-
$files = array('-10-filename.php', '-9-filename.php', '-8-filename.php', '-10-filename.php', '-1-filename.php', '-0-filename.php');
$cmp = function($a, $b){
list($mt, $num1, $name) = explode('-', $a);
list($mt, $num2, $name) = explode('-', $b);
return $num1 - $num2;
};
usort($files, $cmp);
var_dump($files);
Gave me this output:-
array
0 => string '-0-filename.php' (length=15)
1 => string '-1-filename.php' (length=15)
2 => string '-8-filename.php' (length=15)
3 => string '-9-filename.php' (length=15)
4 => string '-10-filename.php' (length=16)
5 => string '-10-filename.php' (length=16)
If you want them sorted in reverse just change the last line in the comparison function to:-
return $num2 - $num1;
As an aside, you may find a comparison of PHP sort functions useful.

Categories