php similar_text function on two arrays - php

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)

Related

How to join string after last array value? [duplicate]

This question already has answers here:
How add a link on comma separated multidimensional array
(2 answers)
Closed 7 months ago.
I am trying to generate a string from an array. Need to concatenate the array values with a small string AFTER the value. It doesn't work for the last value.
$data = array (
1 => array (
'symbol' => 'salad'
),
2 => array (
'symbol' => 'wine'
),
3 => array (
'symbol' => 'beer'
)
);
$symbols = array_column($data, 'symbol');
$string_from_array = join($symbols, 'bar');
echo($string_from_array);
// expected output: saladbar, winebar, beerbar
// output: saladbar, winebar, beer
You can achieve it a few different ways. One is actually by using implode(). If there is at least one element, we can just implode by the delimiter "bar, " and append a bar after. We do the check for count() to prevent printing bar if there are no results in the $symbols array.
$symbols = array_column($data, "symbol");
if (count($symbols)) {
echo implode("bar, ", $symbols)."bar";
}
Live demo at https://3v4l.org/ms5Ot
You can also achieve the desired result using array_map(), as follows:
<?php
$data = [
1 => ['symbol' => 'salad'],
2 => ['symbol' => 'wine'],
3 => ['symbol' => 'beer']
];
echo join(", ", array_map(
fn($v) => "{$v}bar",
array_column($data, 'symbol')
)
);
See live code
Array_map() takes every element of the array resulting from array_column() pulling out the values from $data and with an arrow function, appends the string "bar". Then the new array yielded by array_map has the values of its elements joined with ", " to form the expected output which is then displayed.
As a recent comment indicated you could eliminate array_column() and instead write code as follows:
<?php
$data = [
1 => ['symbol' => 'salad'],
2 => ['symbol' => 'wine'],
3 => ['symbol' => 'beer']
];
echo join(", ", array_map(
fn($row) => "{$row['symbol']}bar",
$data
)
);
See live code
Note while this 2nd way, may appear more direct, is it? The fact is that as array_map iterates over $data, the arrow function contains code that requires dereferencing behind the scenes, namely "$row['symbol']".
The join() function is an alias of implode() which
Returns a string containing a string representation of all the array
elements in the same order, with the glue string between each element.
So you need to add the last one by yourself
$data = array (
1 => array (
'symbol' => 'salad'
),
2 => array (
'symbol' => 'wine'
),
3 => array (
'symbol' => 'beer'
)
);
$symbols = array_column($data, 'symbol');
$string_from_array = join($symbols, 'bar');
if(strlen($string_from_array)>0)
$string_from_array .= "bar";
echo($string_from_array);
You can use array_column and implode
$data = array (
1 => array (
'symbol' => 'salad'
),
2 => array (
'symbol' => 'wine'
),
3 => array (
'symbol' => 'beer'
)
);
$res = implode("bar,", array_column($data, 'symbol'))."bar";
Live Demo
Try this:
$symbols = array_column($data, 'symbol');
foreach ($symbols as $symbol) {
$symbol = $symbol."bar";
echo $symbol;
}
btw, you can't expect implode to do what you expect, because it places "bar" between the strings, and there is no between after the last string you get from your array. ;)
Another way could be using a for loop:
$res = "";
$count = count($data);
for($i = 1; $i <= $count; $i++) {
$res .= $data[$i]["symbol"] . "bar" . ($i !== $count ? ", " : "");
}
echo $res; //saladbar, winebar, beerbar
Php demo

PHP - Get timestamp from filename and sort in array

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)

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.

How to extract array data in PHP variable with foreach?

I need to extract last array data i.e SiteName, Url, Title to the variable in php.
array
'ApplicableProductOfferings' =>
array
0 => string 'EasyDemo' (length=10)
'Artist' => string 'Hello' (length=10)
'ReferralDestinations' =>
array
0 =>
array
'SiteName' => string 'gettyimages' (length=11)
'Url' => string 'http://www.gettyimages.com/detail/160414706' (length=43)
'Title' => string 'Pixie Lott Launches The New BlackBerry Z10' (length=42)
'UrlComp' => string 'http://localhost.com' (length=197)
'UrlPreview' => string 'http://localhost.com' (length=164)
'UrlThumb' => string 'http://localhost.com' (length=82)
'UrlWatermarkComp' => string 'http://localhost.com' (length=197)
'UrlWatermarkPreview' => string 'http://localhost.com
try this.......
foreach($data as $dat)
{
foreach($dat['ReferralDestinations'] as $key => $d)
{
echo $d['SiteName'];
echo $d['Url'];
echo $d['Title'];
}
}
It depends on how you are storing the data in the array. If you have an array that already has the last array data, it's very simple.
foreach ($myArray as $var) {
echo $var;
}
or access individual elements as $myArray['SiteName'], $myArray['Url'] etc..
Assuming you have the above data in an array of arrays called $arrayOfArrays
foreach ($arrayOfArrays as $myArray) {
// $myArray now holds first array, second array etc as the loop is executed
// First time it holds 'ApplicableProductOfferings', second time 'ReferralDesinations'..
// If the array is 'ReferralDesitnations' you can loop through that array
// to get the elements you are looking for SiteName etc as below
foreach ($myArray as $URLElement) {
echo $URLElement;
}
}
$array1 = [];
$array2 = [];
foreach ($array1 as $key=> $val) {
extract($array2, EXTR_IF_EXISTS, $val);
}
// extract() flags => EXTR_IF_EXISTS ...
// http://php.net/manual/ru/function.extract.php

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