I have an array like so:
array{
[39] => src="http://www.google.com/jsapi">
[111] => src="http://www.example.com/wp-content/themes/code.js"
[55] => src="http://www.example.com/wp-content/themes/yui.js"
[1015] => src="wp-content/uploads/website.jpg"
}
Qeustion
What is the best way to find the difference of string ?
What I mean is to check if there are any duplicates.
src="http://www.example.com/wp-content/themes/ is repeated twice.
so if I then had an array like this:
array{
[39] => src="http://www.google.com/jsapi">
[55] => src="http://www.example.com/wp-content/themes/yui.js"
[1015] => src="wp-content/uploads/website.jpg"
}
http://www. is repeated twice.
so the Idea is to compare the string with another and find something that is duplicated and push it to an array ... thats all that I need :)
I am not saying it could be possible, but it would be nice if it could be :)
Community, feel free to optimize the code. I quickly wrote this out.
function findStrDuplicate($str1, $str2)
{
$duplicate = '';
for($i = 0; $i < min(strlen($str1), strlen($str2)); $i++) {
if($str1[$i] != $str2[$i]) {
break;
}
$duplicate .= $str1[$i];
}
return $duplicate;
}
function findArrayPrefixDuplicate($array)
{
$duplicatesArray = array();
for($i = 0; $i < count($array) - 1; $i++) {
for($j = $i+1; $j < count($array); $j++) {
$dup = findStrDuplicate($array[$i], $array[$j]);
if(!empty($dup)) {
$duplicatesArray[] = $dup;
}
}
}
return array_unique($duplicatesArray);
}
$data = array(
'src="http://www.google.com/jsapi"',
'src="http://www.example.com/wp-content/themes/code.js"',
'src="http://www.example.com/wp-content/themes/yui.js"',
'src="wp-content/uploads/website.jpg"'
);
// Remove src="..."
$data = array_map(function ($val) {
return substr($val, 5, strlen($val) - 1);
}, $data);
$result = findArrayPrefixDuplicate($data);
var_dump($result);
Result:
array
0 => string 'http://www.' (length=11)
2 => string 'http://www.example.com/wp-content/themes/' (length=41)
The following link should help with this: http://www.rogerethomas.com/b/14/php-search-string-for
You just need to change the else output to add it to the array and add a while loop in there if you are reiterating over multiple entries
I think that you will probably want to take a look at the suffix tree data structure. Take a look at this post for some ideas:
Fast String Search With Suffix Trees
Related
I want to remove elements from an array with PHP and saw that it is pretty easy with array_splice or unset.
I would like to use this inside another function that takes this array with elements to remove as parameters. However, the function has some other return value and the array should be updated as side effect (array_splice or unset both work by side effect). My code looks as follows:
<?php
function removeSomeElements($arr)
{
for ($i = 0; $i<count($arr); $i++) {
$c = $arr[$i];
if ($c > 2) {
echo "Element $c found at $i\n";
unset($arr[$i]);
}
}
print_r($arr); // misses middle element
return true;
}
$t = [0, 3, 1];
print_r($t); // original array
$success = removeSomeElements($t);
print_r($t); // should be missing middle element, but everything is here
I'm experiencing the same problems with array_splice, that is to say when I replace the call to unset with the following:
array_splice($arr, $i, 1);
$i--;
The parameter of the function is well updated inside the function but not outside. Am I missing something?
Note: I can find a workaround for this quite easily, I just wanted to know if this is possible and why / why not. Thanks in advance!
You need to pass the array by reference &.
Try it like this:
Replace this line:
function removeSomeElements($arr)
With this line:
function removeSomeElements(&$arr)
Test
An alternative method would be to return the altered array in the function, then set the $t variable like so:
<?php
function removeSomeElements($arr)
{
for ($i = 0; $i<count($arr); $i++) {
$c = $arr[$i];
if ($c > 2) {
echo "Element $c found at $i\n";
unset($arr[$i]);
}
}
print_r($arr); // misses middle element
return $arr; // <-- return the altered array
}
$t = [0, 3, 1];
print_r($t); // original array
$t = removeSomeElements($t); // <-- set the variable
print_r($t);
Returns:
Array
(
[0] => 0
[1] => 3
[2] => 1
)
Element 3 found at 1
Array
(
[0] => 0
[2] => 1
)
Array
(
[0] => 0
[2] => 1
)
https://3v4l.org/Jisfv
I am trying to extract qualifying substrings from an array of strings. Some strings in the array have just one qualifying substring, but others may have more. I need to build a flat array of all of these wanted values.
The following is my current Codeigniter method, but it doesn't handle cases when more than one qualifying substring exists.
public function generatenewname()
{
$this->load->helper('directory');
$map = directory_map('./assets/file_upload/md/temp/', FALSE, TRUE);
for ($x = 0; $x < count($map); $x++) {
$newest[$x] = explode(" ", $map[$x]);
for ($y = 0; $y < count($newest[$x]); $y++) {
if (strlen($newest[$x][$y]) >= 7) {
$file[] = $newest[$x][$y];
}
}
}
for ($x = 0; $x < count($file); $x++) {
echo $x . ' ' . $file[$x] . '<br>';
}
}
Assume that my $map array contains this:
$map = [
'BACK PACK BBP160800103 G086-1 8#.JPG',
'BACKPACK BBP160500010 G114-3#1.JPG',
'WSL160800024-WSL160800025 L83-5.JPG',
'IA041017 L83-5.JPG'
];
Desired result:
[
'BBP160800103',
'BBP160500010',
'WSL160800024',
'WSL160800025',
'IA041017'
]
You can match against the patterns based on starting keys.
$array = [
['BACK', 'PACK', 'BBP160800103', '', 'G086-1', '8#.JPG'],
['BACKPACK', 'BBP160500010', 'G114-3#1.JPG'],
['WSL160800024-WSL160800025', 'L83-5.JPG'],
['IA041017', 'L83-5.JPG']
];
$patterns = ['(BBP\w+)', '(WSL\w+)', '(IA\w+)'];
$codes = [];
$matcher = '/' . implode($patterns, '|') . '/';
foreach ($array as $arr) {
array_map(function ($value) use ($matcher, &$codes) {
preg_match_all($matcher, $value, $matches);
foreach($matches as $match) {
$codes = array_merge(array_filter($match), $codes);
}
}, $arr);
}
print_r(array_unique($codes));
// output
Array
(
[0] => IA041017
[2] => WSL160800024
[3] => WSL160800025
[6] => BBP160500010
[8] => BBP160800103
)
Pass your final array to this function to achieve your result.
arraymakking($file);//your array
function arraymakking($arr){
foreach($arr as $key=>$val){
if(strpos($val,'-') !== false){
$res=explode('-',$val);
unset($arr[$key]);
}
}
$result=array_merge($arr,$res);
return $result;
}
More directly than exploding the strings and scavenging through the smitherings, call preg_match_all() on the strings to articulately pick out the qualifying substrings, then unpack those one-or-more substrings inside of an array_push() call.
Code: (Demo)
$result = [];
foreach ($map as $string) {
array_push($result, ...preg_match_all('/\b(?:BBP|WSL|IA)\d{6,9}\b/', $string, $m) ? $m[0] : []);
}
var_export($result);
Try this:
echo $array[0][3]; //BBP160800103
echo $array[2][1]; //BBP160500010
Etc. Refer to the indexing by number. You'd be better off creating your array with named indexes. Like this:
$array = array("Array1"=>array("key1"=>"val1","key2"=>"val2"),"Array2"=>(array("2ndKey1"=>"val1", "2ndKey2"=>"val2));
I am trying to manually sort a PHP array without making use of ksort.
This is how my code looks at the moment:
function my_ksort(&$arg){
foreach($arg as $key1 => $value1){
foreach($arg as $key2 => $value2){
if($key1 > $key2){
$aux = $value2;
$arg[$key2] = $value1;
$arg[$key1] = $aux;
}
}
}
}
It doesn't sort, I can't figure out how to make it sort.
You could try this:
function my_ksort(&$arg)
{
$keys=array_keys($arg);
sort($keys);
foreach($keys as $key)
{
$val=$arg[$key];
unset($arg[$key]);
$arg[$key]=$val;
}
}
I'm sorting the keys separately and then deleting the elements one-by-one and appending them to the end, in ascending order.
I'm using another sorting function (sort()), but if you want to eliminate all available sorting functions from your emulation, sort() is much easier to emulate. In fact, #crypticous's algorithm does just that!
This function return array in ASC. Take in consideration that I'm using goto which is supported in (PHP 5 >= 5.3.0)
function ascending_array($array){
if (!is_array($array)){
$array = explode(",", $array);
}
$new = array();
$flag = true;
iter:
$array = array_values($array); // recount array values with new offsets
(isset($min["max"])) ? $min["value"] = $min["max"] : $min["value"] = $array[0];
$min["offset"] = 0;
for ($i=0;$i<count($array);$i++){
if ($array[$i] < $min["value"]){ // redefine min values each time if statement executed
$min["value"] = $array[$i];
$min["offset"] = $i;
}
if ($flag){ // execute only first time
if ($array[$i] > $min["value"]){ // define max value from array
$min["max"] = $array[$i];
}
$flag = false;
}
if ($i === (count($array)-1)){ // last array element
array_push($new,$min["value"]);
unset($array[$min["offset"]]);
}
}
if (count($array)!=0){
goto iter;
}
print_r($new);
}
$arr = array(50,25,98,45);
ascending_array($arr); // 25 45 50 98
PS. When I was studying php, I wrote this function and now remembered that I had it (that's why I really don't remember what I am doing in it, though fact is it's working properly and hopefully there are comments too), hope you'll enjoy :)
DEMO
I was checking some issue related to this post and i wanted to give my insight about it ! here's what i would have done to implement php's sort :
$array_res = array();
$array = array(50,25,98,45);
$i=0;
$temp = $array[0];
$key = array_search($temp, $array);
while ($i<count($array)-1){
$temp = $array[0];
for($n=0;$n<count($array) ;$n++)
{
if($array[$n]< $temp && $array[$n] != -1 )
{
$temp = $array[$n];
}
else{continue;}
}
//get the index for later deletion
$key = array_search($temp, $array);
array_push($array_res, $temp);
/// flag on those which were ordered
$array[$key] =-1;
$i++;
}
// lastly append the highest number
for($n=0;$n<count($array) ;$n++)
{
if ($array[$n] != -1)
array_push($array_res, $array[$n]);
}
// display the results
print_r($array_res);
This code will display : Array
(
[0] => 25
[1] => 45
[2] => 50
[3] => 98
)
Short and sweet
function custom_ksort($arg)
{
$keys = array_keys($arg);
sort($keys);
foreach($keys as $newV)
{
$newArr[$newV] = $arg[$newV];
}
return $newArr;
}
It looks like your issue is that you're changing "temporary" characters $key1 and $key2 but not the actual arrays. You have to change $arg, not just $key1 and $key2.
Try something like:
$arr = Array(3=>"a",7=>"b");
print_r( $arr );
foreach( $arr as $k=>$v ){
unset($arr[$k]);
$arr[$k+1] = $v;
}
print_r($arr);
What is the easiest way to check if an has array keys that don't match a particular list?
$a = array(
[ignore_me] => "blah blah blah",
[name] => "Don"
);
does_array_have_non_ignored_entries($a); // returns true
I can think of a ton of ways to write this function, didn't know if PHP has a quick solution. Best one I have is this:
$length = count($a);
$ignored_entry = (in_array($a, 'ignore_me') ? 1 : 0;
if ($length - $ignored_entry > 0) {...}
One way to do this, using standard functions, is as follows:
$ignored_keys = array("ignore_me"); // can be extended to ignore several keys
$diff = array_diff_key($array,array_flip($ignored_keys));
if( $diff) {
// there are keys that weren't ignored.
}
How about this?
$count = isset($a['ignore_me']) ? count($a) -1 : count($a);
Substract 1, if that key is found, else use the full length.
Another solution is the array_diff_key function
$count = count(array_diff_key(array('ignore_me'=>null), $a)));
foreach($a as $key => $row)
{
if($key == 'ignore_me')
{
unset($array[$key]);
}
}
$count = count($array);
for this you can use a array in built function as:
$a = array(
[ignore_me] => "blah blah blah",
[name] => "Don"
);
if (array_key_exists("ignore_me",$a))
{
echo "Key exists!";
}
else
{
echo "Key does not exist!";
}
?>
Hi I need help in removing values from an array using a recursive function
$array = [0] => testing,testing1
[1] => testing,testing1,testing2
[2] => testing,testing1,testing2,testing3
[3] => testing,testing1,testing2,testing3,tesing4
[4] => testing,testing1,testing2,testing3,tesing4
[5] => testing,testing1,testing2,testing3,tesing4
[6] => testing,testing1,testing2,testing3,tesing4
[7] => testing,testing1,testing2,testing3,tesing4
I need to check the array count, ie if count(array[0]) == count(array[1]),then reutrn array
else unset(array[value]);
From the above array I have to remove array[0],[1],[2] and return rest of the array values.
I've tried the below code
$idx =10;
$separtor =',';
function array_delete($idx, $array,$separtor) {
$finalvalue = array();
for ($i = 0; $i < $idx; $i++) {
$values = explode($separtor, $array[$i]);
$valuesnext = explode($separtor, $array[$i+1]);
if(count($values) != count($valuesnext) )
{
unset($array[$i]);
// reset($array);
// array_delete($idx, $array,$separtor);
if (is_array($array)) $array = array_delete($idx, $array,$separtor);
$finalvalue = $array;
}else
{
}
//echo $i;
}
return $finalvalue;
//(is_array($array)) ? array_values($array) : null;
//array_delete($idx, $array,$separtor);
}
I'm getting Notice: Undefined offset: 0 when trying calling recursive, going to infinite loop
Do you want to keep the sub-arrays that have the most items? Your descriptions appear to say this.
If so, something like the following would suffice.
// Get maximum number of items in the arrays
$max_count = max(array_map('count', $array));
// Keep only those arrays having $max_count items
$filtered = array_filter($array, function ($a) use ($max_count) {
return count($a) === $max_count;
});
Aside: if you need the filtered array to have zero-based keys, call array_values() on it.
See an example running online.
If I understand correctly, you want to filter the array such that any value in the final array is of the same length as the last element in the source array. In order to avoid mutating an array while iterating over it, this technique builds a fresh array with the elements that match your criteria.
$matchLength = count($mainArray[count($mainArray) - 1]);
$resultArray = array();
for($i = 0; $i < count($mainArray); $i++) {
if(count($mainArray[$i]) == $matchLength) {
$resultArray[] = $mainArray[$i];
}
}
If you happen to be using PHP 5.3 or greater, you can do this quicker with closures and array_filter:
$matchLength = count($mainArray[count($mainArray) - 1]);
$resultArray = array_filter($mainArray, function($element){return count($element) == $matchLength});
Double check the code, I haven't been writing PHP lately, so this is just an idea.
According to the description you gave, it could be just made (check the count of the current and the provious one, if they don't match, remove the previous one).
Example/Demo:
unset($prevKey);
$count = array();
foreach (array_keys($array) as $key) {
$count[$key] = count($array[$key]);
if (isset($prevKey) && $count[$prevKey] !== $count[$key]) {
unset($array[$prevKey]);
}
$prevKey = $key;
}
If you need to re-iterate to take removals into account, a little goto can do the job Demo:
start:
######
unset($prevKey);
$count = array();
foreach (array_keys($array) as $key) {
$count[$key] = count($array[$key]);
if (isset($prevKey) && $count[$prevKey] !== $count[$key]) {
unset($array[$prevKey]);
goto start;
###########
}
$prevKey = $key;
}