I want to insert a element inside a array, but not overwrite any existing elements:
$to_insert = 25;
$elem = 'new';
$arr = array(
5 => 'abc',
10 => 'def',
12 => 'xyz',
25 => 'dontoverwrite',
30 => 'fff',
);
foreach($arr as $index => $val){
if($to_insert == $index){
// here get next free index, in this case would be 26;
$arr[$the_free_index] = $elem;
}
}
How can I do that?
You want a simple loop that starts from $to_insert and increases the loop variable until it finds a value that does not already exist as a key in $arr. So you can use for and array_key_exists:
for($i = $to_insert; array_key_exists($i, $arr); ++$i) ;
$arr[$i] = $elem;
This will correctly insert the element both when the $to_insert key exists and when it does not.
See it in action.
The following code will find the next index not in use, starting at $to_insert:
$to_insert = 25;
$elem = 'new';
for($i = $to_insert; ; $i++)
{
if(!isset($arr[$i]))
{
$arr[$i] = $elem;
break;
}
}
Related
So I'm getting a lot of these errors when I run this code. I'm about to give up and just use the sorting functions baked into PHP. But I would love if anyone could see the problem here. Please see below code. Sorry in advance if it's hard to read.
The array input is fine as print_r outputs exactly as expected, but the actual sorting algorithm just won't work, no matter what I try. The two commented functions at the bottom were used in different trials.
<?php
//this function will pull a string from a txt file and pass characters to an array
function strToArray($file){
if ($handle = fopen($file, 'r')){
$string = fread($handle, filesize($file));
fclose($handle);
}
$strArray = str_split(preg_replace('/\s+/', '', $string)); //regex in preg_replace gets rid of all whitespaces; str_split converts string to array
$arrLen = array_count_values($strArray);
return $arrLen;
}
$arrayWithVal = strToArray("filetest.txt"); //intermediary to pass into next function
print_r($arrayWithVal); //see what I have so far
echo "<hr />";
$newArray = $arrayWithVal;
for ($i = 1; $i < count($newArray); $i++){
for ($j = $i-1; $j >= 0; $j--){
if ($newArray[$j] > $newArray[$j+1]){ //if value on left is bigger than current value
$oldValue = $newArray[$j+1];
$newArray[$j+1] = $newArray[$j];
$newArray[$j] = $oldValue;
//return $newArray;
}
else {
break; //if value on left is smaller, skip to next position
}
}
}
print_r($newArray); //END
/*
function insertionSort($array){
$newArray=$arrayWithVal;
for($j=1; $j < count($newArray); $j++){
$temp = $newArray[$j];
$i = $j;
while(($i >= 0) && ($newArray[$i-1] > $temp)){
$newArray[$i] = $newArray[$i-1];
$i--;
}
$newArray[$i] = $temp;
}
return $array;
}
*/
/*
function insertionSort($arrData){
for ($i=1;$i<count($arrData);$i++){
for ($j=$i-1;$j>=0;$j--){
if ($arrData[$j]>$arrData[$j+1]){ //if value on left is bigger than current value
$oldValue = $arrData[$j+1];
$arrData[$j+1] = $arrData[$j];
$arrData[$j] = $oldValue;
}
else {
break; //if value on left is smaller, skip to next position
}
}
}
return $arrData;
}
*/
?>
EDIT: I should also mention that after it returns the errors, it prints the the same array that the first print_r output.
You are using array_count_values($strArray) function which will return an array using the values of $strArray as keys and their frequency in $strArray as values.
So for ex:
$arrayWithVal will be:
array('some_word'=>3,'other_word'=>4);
You are copying this array into $newArray and then later on you are trying to access $newArray with numeric index : $newArray[$j+1] while $newArray is an associative array.
That is why you are getting undefined offset error.
Exact working code for your problem can be :
//this function will pull a string from a txt file and pass characters to an array
function strToArray($file){
if ($handle = fopen($file, 'r')){
$string = fread($handle, filesize($file));
fclose($handle);
}
$strArray = str_split(preg_replace('/\s+/', '', $string)); //regex in preg_replace gets rid of all whitespaces; str_split converts string to array
$arrLen = array_count_values($strArray);
return $arrLen;
}
$arrayWithVal = strToArray("filetest.txt"); //intermediary to pass into next function
print_r($arrayWithVal); //see what I have so far
$newArray = $arrayWithVal;
$test = array();
foreach($newArray as $v){
$test[] = $v;
}
for ($i = 1; $i < count($test); $i++){
for ($j = $i-1; $j >= 0; $j--){
if ($test[$j] > $test[$j+1]){ //if value on left is bigger than current value
$oldValue = $test[$j+1];
$test[$j+1] = $test[$j];
$test[$j] = $oldValue;
//return $newArray;
}
else {
break; //if value on left is smaller, skip to next position
}
}
}
$result = array();
foreach($test as $k => $v){
$keys_array = array_keys($newArray, $v);
foreach($keys_array as $key){
$result[$key] = $v;
}
}
print_r($result);// to see $result array
If your $newArray is:
Array
(
[some] => 4
[r] => 3
[w] => 6
[t] => 1
[a] => 8
[hell] => 4
)
$result array will be :
Array
(
[t] => 1
[r] => 3
[some] => 4
[hell] => 4
[w] => 6
[a] => 8
)
Its good approach if you are learning PHP but otherwise you should just use inbuild php functions for better time performance.
I hope it helps
Is it possible to find the last occurrence of a value in an array element starting at a specific index value. I have found a partial solution in this post [How can I find the key of the last occurrence of an item in a multidimensional array? but it doesn't allow for starting at a specific index. I am looping thru an array matching an 'id' number. If the 'id' number doesn't exist in the current array index, I would like to search back from that point finding the last occurrence of that value.
$last = "";
foreach($arr as $key => $array) {
if ( $array['id'] === $id) {
$last = $key;
}
}
echo $last."\n\n";
If the array has numeric indexes, you can do that with usual for loop
$last = false;
for($i = $start; $i >= 0; $i--) { // $start - index to start look up
if ( $arr[$i]['id'] === $id) {
$last = $i;
break; // if key is found, stop loop
}
}
if($last !== false)
echo $last."\n\n";
else
echo "Not found" . "\n";
<?php
$myArray = [
"bus" => "blue",
"car" => "red",
"shuttle" => "blue",
"bike" => "green";
];
$findValue = "blue";
$startIndex = "bus";
$continue = false;
$lastIndex = null;
foreach ($myArray as $key => $value)
{
if(!$continue && $key === $startIndex)
{
$continue = true;
} else if($continue) {
if($key === $findValue) {
$lastIndex = $key;
}
}
}
Basically what I'm doing here is only checking the index against first index you're trying to find, if its found that index it'll go on to try and compare the current key's value to the one you're trying to specify.
I would like to know, how can we detect the duplicate entries in array...
Something like
$array = array("192.168.1.1", "192.168.2.1","192.168.3.1","192.168.4.1","192.168.2.1","192.168.2.1","192.168.10.1","192.168.2.1","192.168.11.1","192.168.1.4") ;
I want to get the number of Duplicity used in array (C class unique).
like this
192.168.1.1 = unique
192.168.2.1 = Duplicate
192.168.3.1 = unique
192.168.4.1 = unique
192.168.2.1 = Duplicate
192.168.2.1 = Duplicate
192.168.10.1 = unique
192.168.2.1 = Duplicate
192.168.11.1 = unique
192.168.1.4 = Duplicate (Modified)
I tried this code like this style
$array2 = array() ;
foreach($array as $list ){
$ips = $list;
$ip = explode(".",$ips);
$rawip = $ip[0].".".$ip[1].".".$ip[2] ;
array_push($array2,$rawip);
}
but i am unable to set the data in right manner and also unable to make the loop for matching the data.
modified values
Thanks
SAM
Try this : this will give you the count of each value
$array = array("192.168.1.1", "192.168.2.1","192.168.3.1","192.168.4.1","192.168.2.1","192.168.2.1","192.168.10.1","192.168.2.1","192.168.11.1") ;
$cnt_array = array_count_values($array)
echo "<pre>";
print_r($cnt_array);
$res = array();
foreach($cnt_array as $key=>$val){
if($val == 1){
$res[$key] = 'unique';
}
else{
$res[$key] = 'duplicate';
}
}
echo "<pre>";
print_r($res);
use array_unique($array) function.
it will give you below output.
Array
(
[0] => 192.168.1.1
[1] => 192.168.2.1
[2] => 192.168.3.1
[3] => 192.168.4.1
[6] => 192.168.10.1
[8] => 192.168.11.1
)
And total duplicate count must be :
array_count_values($array)
Try this, hope it'll work
$FinalArray=array();
$arrayLen=count($array);
for($i=0; $i<$arrayLen; $i++)
{
if(!in_array($array[$i],$FinalArray))
$FinalArray[]=$array[$i];
}
Now in $FinalArray you got all the unique ip
Try this:
for ($i = 0; $i < count($array); $i++)
for ($j = $i + 1; $j < count($array); $j++)
if ($array[$i] == $array[$j])
echo $array[$i];
use in_array() function to check value is or not in array
<?php
$output ='';
$array = array(0, 1, 1, 2, 2, 3, 3);
$isArraycheckedvalue = array();
for ($i=0; $i < sizeof($array); $i++)
{
$eachArrayValue = $array[$i];
if(! in_array($eachArrayValue, $isArraycheckedvalue))
{
$isArraycheckedvalue[] = $eachArrayValue;
$output .= $eachArrayValue. " Repated no <br/>";
}
else
{
$isArraycheckedvalue[] = $eachArrayValue;
$output .= $eachArrayValue. " Repated yes <br/>";
}
}
echo $output;
?>
find the Duplicate values in array using php
function array_repeat($arr){
if(!is_array($arr))
return $arr;
$arr1 = array_unique($arr);
$arr3 = array_diff_key($arr,$arr1);
return array_unique($arr3);
}
I have an array of strings of random letters, and I need to know which letters are consistent between the array members. The count of the letters are important.
My method right now is loop through the array, doing a split, then looping through the spitted string to count the occurrences of each letter, then update the array with letter => count
Then do an array_reduce that creates a new array of members who only occur in all arrays. But, it's not working.
<?
$a[] = "emaijuqqrauw";
$a[] = "aaeggimqruuz";
$a[] = "aabimqrtuuzw";
$a[] = "aacikmqruuxz";
$a[] = "aacikmqruuxz";
$a[] = "aaciimqruuxy";
foreach($a as $b){
$n = str_split($b, 1);
foreach($n as $z){
$arr[$z] = substr_count($b, $z);
}
ksort($arr);
$array[] = $arr;
unset($arr);
}
$n = array_reduce($array, function($result, $item){
if($result === null){
return $item;
}else{
foreach($item as $key => $val){
if(isset($result[$key])){
$new[$key] = $val;
}
}
return $new;
}
});
foreach($n as $key => $val){
echo str_repeat($key, $val);
}
This returns aaiimqruu - which is kinda right, but there's only 2 i's in the last element of the array. There's only one i in the rest. I'm not sure how to break that down farther and get it to return aaimqruu- which I'll then pop into a SQL query to find a matching word, aquarium
There's array_intersect(), which is most likely what you'd want. Given your $a array, you'd do something like:
$a = array(.... your array...);
$cnt = count($a);
for($i = 0; $i < $cnt; $i++) {
$a[$i] = explode('', $a[$i]); // split each string into array of letters
}
$common = $a[0]; // save the first element
for($i = 1; $i < $cnt; $i++) {
$common = array_intersect($common, $a[$i]);
}
var_dump($common);
How about you do it this way? Finds out the occurrence of an item throughout the array.
function findDuplicate($string, $array) {
$count = 0;
foreach($array as $item) {
$pieces = str_split($item);
$pcount= array_count_values($pieces);
if(isset($pcount[$string])) {
$count += $pcount[$string];
}
}
return $count;
}
echo findDuplicate("a",$a);
Tested :)
Gives 12, using your array, which is correct.
Update
My solution above already had your answer
$pieces = str_split($item);
$pcount= array_count_values($pieces);
//$pcount contains, every count like [a] => 2
Seems like array_reduce is the best function for what this purpose, however I just didn't think of adding a conditional to give me the desired effect.
$new[$key] = ($result[$key] > $val) ? $val : $result[$key];
to replace
$new[$key] = $val;
did the trick.
I want to select a random value from a array, but keep it unique as long as possible.
For example if I'm selecting a value 4 times from a array of 4 elements, the selected value should be random, but different every time.
If I'm selecting it 10 times from the same array of 4 elements, then obviously some values will be duplicated.
I have this right now, but I still get duplicate values, even if the loop is running 4 times:
$arr = $arr_history = ('abc', 'def', 'xyz', 'qqq');
for($i = 1; $i < 5; $i++){
if(empty($arr_history)) $arr_history = $arr;
$selected = $arr_history[array_rand($arr_history, 1)];
unset($arr_history[$selected]);
// do something with $selected here...
}
You almost have it right. The problem was the unset($arr_history[$selected]); line. The value of $selected isn't a key but in fact a value so the unset wouldn't work.
To keep it the same as what you have up there:
<?php
$arr = $arr_history = array('abc', 'def', 'xyz', 'qqq');
for ( $i = 1; $i < 10; $i++ )
{
// If the history array is empty, re-populate it.
if ( empty($arr_history) )
$arr_history = $arr;
// Select a random key.
$key = array_rand($arr_history, 1);
// Save the record in $selected.
$selected = $arr_history[$key];
// Remove the key/pair from the array.
unset($arr_history[$key]);
// Echo the selected value.
echo $selected . PHP_EOL;
}
Or an example with a few less lines:
<?php
$arr = $arr_history = array('abc', 'def', 'xyz', 'qqq');
for ( $i = 1; $i < 10; $i++ )
{
// If the history array is empty, re-populate it.
if ( empty($arr_history) )
$arr_history = $arr;
// Randomize the array.
array_rand($arr_history);
// Select the last value from the array.
$selected = array_pop($arr_history);
// Echo the selected value.
echo $selected . PHP_EOL;
}
How about shuffling the array, and popping items off.
When pop returns null, reset the array.
$orig = array(..);
$temp = $orig;
shuffle( $temp );
function getNextValue()
{
global $orig;
global $temp;
$val = array_pop( $temp );
if (is_null($val))
{
$temp = $orig;
shuffle( $temp );
$val = getNextValue();
}
return $val;
}
Of course, you'll want to encapsulate this better, and do better checking, and other such things.
http://codepad.org/sBMEsXJ1
<?php
$array = array('abc', 'def', 'xyz', 'qqq');
$numRandoms = 3;
$final = array();
$count = count($array);
if ($count >= $numRandoms) {
while (count($final) < $numRandoms) {
$random = $array[rand(0, $count - 1)];
if (!in_array($random, $final)) {
array_push($final, $random);
}
}
}
var_dump($final);
?>
Php has a native function called shuffle which you could use to randomly order the elements in the array. So what about this?
$arr = ('abc', 'def', 'xyz', 'qqq');
$random = shuffle($arr);
foreach($random as $number) {
echo $number;
}
key != value, use this:
$index = array_rand($arr_history, 1);
$selected = $arr_history[$index];
unset($arr_history[$index]);
I've done this to create a random 8 digit password for users:
$characters = array(
"A","B","C","D","E","F","G","H","J","K","L","M",
"N","P","Q","R","S","T","U","V","W","X","Y","Z",
"a","b","c","d","e","f","g","h","i","j","k","m",
"n","p","q","r","s","t","u","v","w","x","y","z",
"1","2","3","4","5","6","7","8","9");
for( $i=0;$i<=8;++$i ){
shuffle( $characters );
$new_pass .= $characters[0];
}
If you do not care about what particular values are in the array, you could try to implement a Linear Congruential Generator to generate all the values in the array.
LCG implementation
Wikipedia lists some values you can use, and the rules to select the values for the LCG algorithm, because the LCG algorith is deterministic it is guaranteed not to repeat a single value before the length of the period.
After filling the array with this unique numbers, you can simply get the numbers in the array 1 by 1 in order.
$isShowCategory = array();
for ($i=0; $i <5 ; $i++) {
$myCategory = array_rand($arrTrCategoryApp,1);
if (!in_array($myCategory, $isShowCategory)) {
$isShowCategory[] = $myCategory;
#do something
}
}
Easy and clean:
$colors = array('blue', 'green', 'orange');
$history = $colors;
function getColor($colors, &$history){
if(count($history)==0)
$history = $colors;
return array_pop( $history );
}
echo getColor($colors, $history);