PHP array_push index retention - php

I am looping through an array which itself contains array to find indexes of values 5 & 6.
Upon finding these indexes, I push the matched array, using array_push, into a another array. My application depends on maintaining the array indexes but array_push resets the keys to 0, 1, 2 etc rather than the matched 5, 6, 7 etc.

Rather than calling array_push you can add element this way:
$arr[5] = array("foo", "bar");
$arr[6] = array("red", "blue");
$arr[7] = array("123", "567");

Would that do or did I miss something?
$newArray = array();
foreach( $myArrays as $myArray )
if( ($result = array_search(5, $myArray)) || ($result = array_search(6, $myArray))
$newArray[$result] = $myArray[$result];

Related

How to get the exact value of the last array index in PHP?

Currently i have an array $newArr with some elements as shown in picture below. How do I know the last digit of the array index (highlighted in yellow)?
This is important because, if later I wanted to insert a new record into this $newArr array, I could just
$newArr[$the_variable_that_holds_the_last_digit + 1] = ['foo', 'bar'];
otherwise the whole array overwrite if
$newArr = ['foo', 'bar'];
I think you are looking for end pointer
$array = array(
'a' => 1,
'b' => 2,
'c' => 3,
);
end($array); // it will point to last key
$key = key($array); // get the last key using `key`
Assuming you have the numerically indexed array, the last index on your array is :
$last_index = count($newArr) -1;
if However your keys are not sequential, you can do this:
end($newArr);
$last_key = key($newArr);
I think you can try this
$array = end($newArr);
$last_index = key($array);//Its display last key of array
For more details, please follow this link.
If the only reason is to not overwrite the values you can use [] which means add new value.
$arr = [1,2,3,4];
var_dump($arr);
// incorrect way:
$arr = [1,2];
var_dump($arr);
//correct way
$arr = [1,2,3,4];
$arr[] = [1,2];
var_dump($arr);
See here for output: https://3v4l.org/ZTg28
The "correct way" will in the example above input a new array in the array.
If you want to add only the values you need to insert them one at the time.
$arr[] = 1;
$arr[] = 2;

PHP arsort issue with keys

$vals = array(51, 23, 77, 3, 8, 31, 17, 102, 87);
arsort($vals);
From here, how can I get the keys of the 3 first values? If I do $vals[0] it won't work because it'll return me the original [0] key before the arsort.
I want to get the original keys of 102, 87 and 77 after arsort.
Depending on what you need it for, one way is
$keys = array_keys($vals);
$keys[0] will contain the first key.
$vals[$keys[0]] will contain the first value.
An alternate way
$part = array_slice($vals, 0, 3, true);
$part will contain three $key => $value pairs for the first three entries.
And for the first three keys, you can mix and match the above, such as:
$firstThree = array_keys(array_slice($vals, 0, 3, true));
$firstThreeKeys = array_slice(array_keys($vals), 0, 3);
echo join(', ', $firstThreeKeys);
I think I have found a method, maybe not the best however:
reset($arr); $key1=key($arr);
next($arr); $key2=key($arr);
next($arr); $key3=key($arr);
You could use array_keys()?
Alternatively, loop through the sorted array with a foreach and you can still get the keys:
$i = 0;
$numKeysToGet = 3;
$keys = array();
foreach ($vals as $k => $v) if ($i < $numKeysToGet) {
$keys[] = $k;
$i++;
} else break;
// $keys now contains the first three array keys
arsort saves key=>value relationship, so it's usualy used for associative arrays (hash). For your needs try to sort value=>key array instead of your key=>value with the standart sotring function. Otherwise you can use foreach loop (limit it with 3 iterations) to get the keys.

Remove first 2 from Array

I have this simple array and I'd like to know how I can stop the first 2 segments from showing.
if(preg_match_all('/<td[^>]*class="sourceNameCell">(.*?)<\/td>/si', $printable, $matches, PREG_SET_ORDER));{
foreach($matches as $match) {
$data = "$match[1]";
$array = array();
preg_match( '/src="([^"]*)"/i', $data, $array ) ;
print_r("$array[1]") ;
}
Any help would be great, Thanks!
Use array_slice:
$output = array_slice($input, 2);
Stop from showing or removing?
for removing:
$array = array();
preg_match( '/src="([^"]*)"/i', $data, $array ) ;
// The following lines will remove values from the first two indexes.
unset($array[0]);
unset($array[1]);
// This line will re-set the indexes (the above just nullifies the values...) and make a new array without the original first two slots.
$array = array_values($array);
// The following line will show the new content of the array
var_dump($array);
Hope this helps!
Use array_slice($array, 2, count($array)) or make your regexp skip the first two if possible.
You could also invoke array_shift() twice on the array. This might be more optimal since it shouldn't need to make a copy of the array.
You could use array_splice to remove elements from array.
array_splice — Remove a portion of the array and replace it with something else
Elements are removed from original array and returned
$input = array("red", "green", "blue", "yellow", "black");
$part = array_splice($input, 1, 2);
var_dump($input);
var_dump($part);
See PHP fiddle

How to convert a simple array to an associative array?

What is the fastest way to convert a simple array to an associative array in PHP so that values can be checked in the isset($array[$value])?
I.e. fastest way to do the following conversion:
$array = array(1, 2, 3, 4, 5);
$assoc = array();
foreach ($array as $i => $value) {
$assoc[$value] = 1;
}
Your code is the exact equivalent of:
$assoc = array_fill_keys(array(1, 2, 3, 4, 5), 1); // or
$assoc = array_fill_keys(range(1, 5), 1);
array_flip(), while it may work for your purpose, it's not the same.
PHP ref: array_fill_keys(), array_flip()
If anyone is still wondering how to do this, there is an easier solution for this by using the array_combine function.
$array = array(1, 2, 3, 4, 5);
$assoc = array_combine($array,$array);
array_flip() is exactly doing that:
array_flip() returns an array in flip order, i.e. keys from trans become values and values from trans become keys.
Note that the values of trans need to be valid keys, i.e. they need to be either integer or string. A warning will be emitted if a value has the wrong type, and the key/value pair in question will not be flipped.
If a value has several occurrences, the latest key will be used as its values, and all others will be lost.
But apart from that, there is only one type of array in PHP. Even numerical ("simple", as you call it) arrays are associative.
Simply use this logic
$var1 = json_encode($arr1, JSON_FORCE_OBJECT);
$var1 = json_decode($var1);
where $arr1 is the array that has to be converted to associative array.
This can be achieved by json_encode and the json_decode the same
function simple_to_associative($array) {
$new_array = [];
$i = 0;
$last_elem = end($array);
$nr_elems = count($array);
foreach ($array as $index=>$value) {
if($i % 2 == 0 && $last_elem == $value) {
$new_array[$value] = '';
} elseif($i % 2 == 0) {
$new_array[$value] = $array[$index + 1];
}
$i++;
}
return $new_array;
}
Would work on any simple array of unlimited elements.

Efficient algorithm for detecting matches

I'm looking for an efficient algorithm for detecting equal values in an array of integers N size. It must return the indices of the matches.
Alas, I can't think of anything more clever then brute force with two loops.
Any help will be appreciated.
Thanks!
You could intersect the array. This finds all the values of array2 that are in array1
$array1 = array("a" => "green", "b" => "brown", "c" => "blue", "red");
$array2 = array("a" => "green", "yellow", "red");
$result_array = array_intersect_assoc($array1, $array2);
print_r($result_array);
Would return
Array
(
[a] => green
)
It returns an array with all of the keys and values of the matches. Basically you can provide an infinite number of arguments to the array_insert_assoc:
array_intersect_assoc($base_array, $arr1, $arr2 ...);
It will search $base_array for the values that are in all the subsequent arrays. That means that the key and value will be taken from the $base_array
You could also compare the keys by using:
array_intersect_keys($base_array, $arr1, $arr2, $arr3);
These loops are O(N^2). Is N big? If so, can you sort the array O(NlogN), then scan it O(N)? ... or am I missing something?
You can use a set to hold the recent values. For example,
results = empty list
set = empty set
foreach key, val in array:
if val is not in set: add val to set
else: add key to results
return results
Each look up of set is O(1), so this algo will results in O(n) instead of O(n^2) if nested-loop is used.
In case you want to keep track of multi-occurence like this array 1, 2, 3, 3, 2, 1 you can use a hash table with key is the value and value (of the corresponding key in table) is the list of indices. The result for the given array will look lik {1:0, 5; 2: 1, 4; 3: 2, 3}.
results = empty hashtable
for each key, val in array:
if val is not in results:
results[val] = new list()
results[val].append(key)
return results
Perhaps this?
$arr = array_map('unserialize', array_unique(array_map('serialize', $arr)));
From the question: How to remove duplicated 2-dimension array in PHP?
if ($arr !== array_map('unserialize', array_unique(array_map('serialize', $arr))))
{
// found duplicates
}
You don't have to go through all the array again for each element. Only test an element with the subsequent element in the array:
$array = /* huge array */;
$size = count($array);
for($i = 0; $i < $size; $i++)
{
for($j = $i + 1; $j < $size; $j++) // only test with the elements after $i
{
if($array[$i] == $array[$j])
return true; // found a duplicate
}
return false; // found no duplicate
}
That's the most efficient way I can think of. Adapt it to your need as you will.
If one of your arrays is reasonably static (that is you are comparing to the same array several times ) you could invert it.
That is set up another array which is keyed by value and returns the index into the real array.
$invert = array();
foreach ($cmptoarray as $ix => $ival) {
$invert[$ival] = $ix;
}
Then you simply need an if ( isset($invert[$compfrmarray[$i]) ) .... to check the number.
Note: this is only worth doing if you compare against the same array several times!
Just use an associative array mapping a value to its index:
foreach($array1 as $index => $value) {
$aa[$value] = $index;
}
foreach($array2 as $index => $value) {
if(isset($aa[$value])) {
echo 'Duplicate: . Index 1: '.$aa[$value].' Index 2: '.$index.'.';
}
}

Categories