search through array and find 1 couple optimally? - php

Let`s suppose we have a simple (non-assoc) array with 100001 values and these values set in unsorted order like 45, 12, 32, 23. We know that in this array is 1 couple of numbers, how to find it optimally - not via 2 foreach loops and even not via 2 for loops with 100001/2 division?

Use array_count_values:
$result=array_count_values($arr);
$value=array_search(2, $result);
print $value;

Since your array is not sorted, the ONLY search method other than random scatteryshot is to scan the array sequentially and look for your two numbers:
$first_key = null;
$second_key = null;
foreach($array as $key => $val) {
if ($val == $first_number) {
$first_key = $key;
}
if ($val == $second_number) {
$second_key = $key;
}
if (!is_null($first_key) && !is_null($second_key)) {
break;
}
}
Once both numbers are found, or you reach the end of the array, the loop will exit.

Related

Generating a series of sequential arrays of version-like values in PHP

I've been banging my head against this problem for a while. I feel like it should be simple, but I'm having a hard time coming up with a solution.
I'm looking to pre-populate a database, and I need to create SQL statements with some foreign key values. It would be tedious to hand-code them, so naturally I decided to do it in code.
What I want are series of arrays that have values as such:
[1]
[2]
[3]
[1,1]
[1,2]
[1,3]
[2,1]
[2,2]
...
[1,1,1]
[1,1,2]
[1,1,3]
...
[3,1,1]
...
[3,3,3]
I want to specify the number of values in the array, and the numerical value at which it causes the preceeding value to roll over.
In the example I gave above, it would be like generate(3,3), since the maximum number of elements is 3, and the highest value is 3.
How could I write some code that would give me this series of arrays?
This is a recursive function that will generate each of the combinations of the ranges up to the maximum value, with elements in each array from 1 to the number specified:
function generate($elements, $maxvalue) {
if ($elements == 0) return array();
$result = array();
foreach (range(1, $maxvalue) as $el) {
$result[] = array($el);
}
foreach (range(1, $maxvalue) as $el) {
foreach (generate($elements - 1, $maxvalue) as $arr) {
$result[] = array($el, ...$arr);
}
}
return $result;
}
$combs = generate(3, 3);
Output is too long to show here but can be seen in this demo on 3v4l.org
Note for PHP < 7.4, replace
$result[] = array($el, ...$arr);
with
$result[] = array_merge(array($el), $arr);
Here's a version using generators (which may be slightly easier on memory than pure arrays):
function generate(int $elementsCount, int $maxValue, array $current = []): \Generator
{
for ($value = 1; $value <= $maxValue; $value++) {
yield [...$current, $value];
}
if ($elementsCount > 1) {
for ($value = 1; $value <= $maxValue; $value++) {
yield from generate($elementsCount - 1, $maxValue, [...$current, $value]);
}
}
}
Exemple usage + debug/print:
$combinations = generate(3, 3);
print_r(iterator_to_array($combinations, false));
Demo

How to count the number of occurence of images in an array REGEX

I have an array something like this
ARRAY[0][DATAROOT.PROPIEDADES.FOTO1][0]
ARRAY[0][DATAROOT.PROPIEDADES.FOTO2][0]
ARRAY[0][DATAROOT.PROPIEDADES.FOTO3][0]
ARRAY[0][DATAROOT.PROPIEDADES.FOTO4][0]
I have to write a script to count the number of the photos in the array:
$x = "DATAROOT.PROPIEDADES.FOTO";
$ct = 8; // This is the number of image I am passing fixed variable
I want to get that using the array I need to find out a way that will count the array
that has column name DATAROOT.PROPIEDADES.FOTO with 1, 2,3 etc in the end.
This I am not able to do
for($tt=1;$tt<=$ct;$tt++)
{
$k=$x.$tt;
$result[]=$this->ARRAY[0][$k][0];
}
Can any one help me in this .
Thanks in Advance
As an alternative, you could just get those elements inside the parent array whose keys has that substring:
$x = 'DATAROOT.PROPIEDADES.FOTO';
foreach($this->ARRAY[0] as $k => $value) {
if(strpos($k, $x) !== false) {
$result[] = $value[0];
}
}
Or:
foreach($this->ARRAY[0] as $k => $value) {
if(preg_match('~DATAROOT\.PROPIEDADES\.FOTO\d+~', $k)) {
$result[] = $value[0]
}
}

Removing successive duplicate occurrences in an array

Is there any way that I can remove the successive duplicates from the array below while only keeping the first one?
The array is shown below:
$a=array("1"=>"go","2"=>"stop","3"=>"stop","4"=>"stop","5"=>"stop","6"=>"go","7"=>"go","8"=>"stop");
What I want is to have an array that contains:
$a=array("1"=>"go","2"=>"stop","3"=>"go","7"=>"stop");
Successive duplicates? I don't know about native functions, but this one works. Well almost. Think I understood it wrong. In my function the 7 => "go" is a duplicate of 6 => "go", and 8 => "stop" is the new value...?
function filterSuccessiveDuplicates($array)
{
$result = array();
$lastValue = null;
foreach ($array as $key => $value) {
// Only add non-duplicate successive values
if ($value !== $lastValue) {
$result[$key] = $value;
}
$lastValue = $value;
}
return $result;
}
You can just do something like:
if(current($a) !== $new_val)
$a[] = $new_val;
Assuming you're not manipulating that array in between you can use current() it's more efficient than counting it each time to check the value at count($a)-1

Compare two arrays and merging in PHP

I have two arrays:
$array1 = array(1=>1,10=>1,12=>0,13=>13);
$array2 = array(1=>"Hello",10=>"Test",12=>"check",13=>"error");
Here $array1 has keys and values. Now I want to take the first value from $array1(as 1) and I want to check if this is repeated in this array .
Here 1 is repeated two times so I want to take the two keys 1,10 and display the corresponding values of these keys from $array2. If the value in $array1 is not repeated then I want to just display the value of this key from $array2.
I want to get the output as follows:
Hello Test
check
error
That means in $array1 1,10 keys have the same value so the value of 1 and the value of 10 from $array2 is merged then displayed.
Like 12 has 0 this is not repeated so simply take value of 12 from $array2.
Like 13.
How can I do this?
<?php
$array1 = array(1=>1,10=>1,12=>0,13=>13);
$array2 = array(1=>"Hello",10=>"Test",12=>"check",13=>"error");
$groupedKeys = array();
foreach($array1 as $key=>$arr){
$groupedKeys[$arr][] = $key;
}
foreach($groupedKeys as $key => $groupedKeyArr){
foreach($groupedKeyArr as $groupedKey){
echo $array2[$groupedKey];
}
echo "<br /> ";
}
?>
http://codepad.org/9R9s5lTM
There is a built in function that returns an array with the number of times a value is repeated http://php.net/manual/en/function.array-count-values.php
This is really rough, but a simple way of doing it could be:
<?
$array1 = array(1=>1,10=>1,12=>0,13=>13);
$array2 = array(1=>"Hello",10=>"Test",12=>"check",13=>"error");
$prev = $array1[1];
foreach($array1 as $key => $val)
{
if($val != $prev && $key != 1)
{
echo '<br />';
}
echo $array2[$key].' ';
$prev = $val;
}
?>
Example: http://codepad.org/OpLdtStp
This assumes that you're first key is always going to be 1 by the way.
I am providing you a function returns an array with the number of times a value is repeated in an array(as values) and values as the keys. Further task is not difficult.
function check_number_of_times_elements_occur_in_array($a)//returns values of array as keys, associating values being their total occurences in the array
{
$r=array();
foreach($a as $v)
++$r[$v];
return $r;
}
I think this will do for you..
function test($array1,$array2) {
$repeated_values = array_count_values($array1);
foreach($repeated_values as $key => $value){
if($value > 1) {
foreach($array1 as $key1 => $value1){
if($key == $value1){
$repeated_values_keys[] = $key1;
}
}
}
}
$str_top = "";
foreach($repeated_values_keys as $k){
$str_top .= $array2[$k]." ";
}
echo $str_top.'<br/>';
foreach($array2 as $key2 => $value){
if(!in_array($key2,$repeated_values_keys)){
echo $value.'<br/>';
}
}
}

PHP: Getting to a key in mulitdimensional array?

I have an array like
$myArray =array
(
"0"=>array("dogs",98),
"1"=>array("cats",56),
"2"=>array("buffaloes",78)
)
How can I get a key by providing a value?
e.g. if i search for "buffaloes" array_search may return "2".
Thanks
$myArray =array
(
"0"=>array("dogs",98),
"1"=>array("cats",56),
"2"=>array("buffaloes",78)
);
function findInArray($term, $array) {
foreach($array as $key => $val) {
if(in_array($term, $val, true)) {
return $key;
}
}
}
echo findInArray('buffaloes', $myArray); // 2
echo findInArray(78, $myArray); // 2
function asearch($key, $myArray) {
for ($i = 0; $i < sizeof($myArray); $i++) {
if ($myArray[$i][0] == $key) {
return $i;
}
}
return -1; # no match
}
Though, you'd probably want to restructure your array to:
$myarray = array(
'dogs' => 98,
'cats' => 56,
'buffaloes' => 78
);
And just do:
$myArray['buffaloes']; # 78
The only way you can do it is to iterate over every item and preform a Linear Search
$i = -1;
foreach ($myArray as $key => $item){
if ( $item[0] == 'buffaloes' ){
$i = $key;
break;
}
}
//$i now holds the key, or -1 if it doesn't exist
As you can see, it is really really inefficient, as if your array has 20,000 items and 'buffaloes' is the last item, you have to make 20,000 comparisons.
In other words, you need to redesign your data structures so that you can look something up using the key, for example a better way may be to rearrange your array so that you have the string you are searching for as the key, for example:
$myArray['buffaloes'] = 76;
Which is much much faster, as it uses a better data structure so that it only has to at most n log n comparisons (where n is the number of items in the array). This is because an array is in fact an ordered map.
Another option, if you know the exact value of the value you are searching for is to use array_search
I never heard of built in function. If you want something more general then above solutions you shold write your own function and use recursion. maybe array_walk_recursive would be helpful
You can loop over each elements of the array, testing if the first element of each entry is equal to "buffaloes".
For instance :
foreach ($myArray as $key => $value) {
if ($value[0] == "buffaloes") {
echo "The key is : $key";
}
}
Will get you :
The key is : 2
Another idea (more funny ?), if you want to whole entry, might be to work with array_filter and a callback function that returns true for the "bufalloes" entry :
function my_func($val) {
return $val[0] == "buffaloes";
}
$element = array_filter($myArray, 'my_func');
var_dump($element);
Will get you :
array
2 =>
array
0 => string 'buffaloes' (length=9)
1 => int 78
And
var_dump(key($element));
Gves you the 2 you wanted.

Categories