Insert element into order position of array? - php

All values of array $A are string the same length.
$A = Array
(
[0] => 03
[1] => 04
[2] => 05
[3] => 06
// [4] => 07 // "07" before "04" position
[4] => 04
[5] => 05
[6] => 06
// [8] => 07 // "07" before "08" position
[7] => 08
[8] => 03
[9] => 04
[10] => 05
[11] => 06
[12] => 07 // it is existing
[13] => 08
) ;
I want to Insert the "07" element if it is not existing before "04" or "08" position.start from position 1
So It will be after changed
$A = Array
(
[0] => 03
[1] => 04
[2] => 05
[3] => 06
[4] => 07 // just appended
[5] => 04
[6] => 05
[7] => 06
[8] => 07 // just append
[9] => 08
[10] => 03
[11] => 04
[12] => 05
[13] => 06
[14] => 07
[15] => 08
) ;
Anybody know how to do this ,help me please?

There would be "prettier" ways to do this but, as intended...
iterate the array
if the current value is equal to 7 minus 1 you will insert a new value there
create a function "insert_into_array" that:
a) Splits your array in two (look at array_chunk)
b) POPs your element to the end of the first array (array_pop)
c) merges your two arrays back (array_merge)
I've abstained from writing any code as this is probably homework and, writing code, even if you're not really deep thinking the problem will push you a long way to passing the exam...

not the most beautiful solution, but should do the job:
$b = array();
for($i=0;$i<count($A);$i++){
$b[] = $A[$i];
if(($i<count($A) - 1) && ($A[$i+1]<$A[$i] || ($A[$i+1] == '08')) && $A[$i] < '07')
$b[] = '07';
}
var_dump($b);

First, find the gaps in your array, that is the positions where there's 06 but not a following 07:
$positions = array();
foreach ($A as $k => $v) {
if (isset($last) && $last != $v - 1 && $last == '06') {
$positions[] = $k;
}
$last = $v;
}
Then, insert them:
$count = 0;
foreach ($positions as $pos) {
array_splice($A, $pos + ($count++), 0, '07');
}
That's it.

//make sure the array is numeric:
$A = array_values($A);
foreach(array('04','08') as $search){
$positions = array_keys($A,$search);
rsort($positions);
foreach($positions as $key){
if($key==0 || $A[$key-1] != '07'){
array_splice($A,$key,0,'O7');
}
}
}

In 2017, I've found 2 beautiful methods that is part of nette\utils package.
Arrays::insertBefore()
Arrays::insertAfter()
They do job perfectly!
Just run:
composer require nette/utils
and use Arrays class or inspire in their code.

Related

Increment a variable with numeric and uppercase letter

Can you tell me how I can increment a variable in PHP from 00 to ZZ ?
With A5, 8R, GG...
I tried this but it's just for letter :
for($i="AA"; $i<="ZZ" AND strlen($i)<=2; $i++)
Thank you
i created a little snippet that should demonstrate how you can use range($start,$end) to create what you are looking for
<?php
//create an array with all values from 0-9 and A-Z
$range = array_merge(range("0","9"),range("A","Z"));
//create counter-aray
$counter = array();
//loop through the range
foreach($range as $value1){
foreach($range as $value2){
$counter[] = $value1.$value2;
}
}
//show the counter
print_r($counter);
?>
result:
Array
(
[0] => 00
[1] => 01
[2] => 02
[3] => 03
[4] => 04
[5] => 05
[6] => 06
[7] => 07
[8] => 08
[9] => 09
[10] => 0A
[11] => 0B
[12] => 0C
[13] => 0D
[14] => 0E
[15] => 0F
[16] => 0G
[17] => 0H
[18] => 0I
[19] => 0J
[20] => 0K
[21] => 0L
.....many more values follow here
)
feel free to ask questions if you need further explaination
It actually sounds as if you are trying to add numbers in base 36. Since PHP can convert between bases, you could add the numbers in base 10 then convert into base 36.
for($i = 0; $i <= base_convert("zz", 36, 10); $i++) {
echo(str_pad(strtoupper(base_convert($i, 10, 36)), 2, "0", STR_PAD_LEFT) . PHP_EOL);
}
$i is an integer in base 10 that will loop from 0 to 1295. (zz in base 10.)
base_convert converts $i from base 10 to base 36.
strtoupper converts the resulting string to uppercase so you get AA instead of aa.
str_pad will add leading 0s to convert values such as 0 to 00.

Unset(remove) array key in php

Following is my $newArr0 which is an array of objects.
Array
(
[0] => stdClass Object
(
[created_at] => Mon Dec 08 03:04:47 +0000 2014
[text] => How a individual man can adopt a village in andhra real guds needed hats off to you MASTER BLASTER #Sachin
[source] => Twitter Web Client
)
[1] => stdClass Object
(
[created_at] => Sun Dec 07 17:23:25 +0000 2014
[text] => #two #cool #peoples ..#Coolfieee ..#me nd #Sachin http://t.co/JU971nWAPo
[source] => Instagram
[2] => stdClass Object
(
[created_at] => Sun Dec 07 15:18:22 +0000 2014
[text] => Snga hit 90 odi international fifty...can he hit 6 more to break sachin s fifty record ..#sachin 96 odi fifty ...
kya lgta h tod dega record
[source] => Twitter Web Client
)
[3] => stdClass Object
[created_at] => Sun Dec 07 14:50:53 +0000 2014
[text] => #jeeturaaj Jeeturaaj want #sachin chi book pahje, please give #Sachin #playingitmyway ......:)
[source] => Twitter Web Client
)
[4] => stdClass Object
[created_at] => Sun Dec 07 14:33:49 +0000 2014
[text] => RT #UthMag: Old... http://t.co/b1HMzE3TZI #BCCI #cricket #featured #global #ICC #india #littlemaster #News #ODI #retire #sachin #sports #te…
[source] => Twitter for Android
)
)
I am trying to drop a key with source name from the array, so I tried this code -
foreach ($newArr0 as $nkey1 => $nval1) {
if($nkey1 == "source") {
unset($newArr0["source"]);
}
}
But it is not removing the key, from $newArr0 Let me know what I am doing wrong here.
First off, its a collection of objects inside the array, so you'd use the -> arrow operator on each object inside your loop. Then, alternatively, you could reference each copy of the object inside the foreach and make your unset.
foreach($newArr0 as &$nval1) {
// for each object inside `$newArr0` is in `$nval1`
unset($nval1->source);
// unset $nval1's source
}
<?php
$newArr = array();
foreach ($newArr0 as $key => $value) {
unset($value->source);
$newArr[$key] = $value;
}
$newArr0 = $newArr;
Demo
Here:
foreach ($array as $key => & $object) {
if ($object->source === 'source') {
unset($array[$key]);
}
}

Change key of an array PHP

I have this array $theme_name
Array
(
[0] => template0
[1] => template1
[2] => template2
[3] => template3
[4] => template4
[5] => template5
[6] => template6
)
and this other array that has the same lenght $theme_info
Array
(
[0] => my template n 00
[1] => my template n 01
[2] => my template n 02
[3] => my template n 03
[4] => my template n 04
[5] => my template n 05
[6] => my template n 06
)
Basically what I want is to have this array :
Array
(
[template0] => my template n 00
[template1] => my template n 01
[template2] => my template n 02
[template3] => my template n 03
[template4] => my template n 04
[template5] => my template n 05
[template6] => my template n 06
)
Why this won't work ?
foreach ($themes_info as $key => $value) {
include($value['directory']) ;
$theme_info[] = $info;
$theme_name[] = $value['name'];
}
foreach ($theme_name as $key => $value) {
$value = $theme_info[$key];
}
FYI $themes_info have all the themes with names and directories emplacement.
Use array_combine():
$result = array_combine($theme_name, $theme_info);
Demo
You can do this far easier in PHP. Just like this:
for ($i = 0; $i < count($themes_info); $i++) {
include($value['directory']);
$theme_info[] = $info;
$theme_name["someKey$i"] = $value['name'];
}
And replace someKey with your prefered key for that array. Or for any other array for that matter.

Finding average of same key values of an associate array

I've have an array such as
//$ary, $ary contains some 80 entries, I'm showing only the first 10
Array
(
[0] => Array
(
[December 2012] => 58
)
[1] => Array
(
[November 2012] => 84
)
[2] => Array
(
[December 2012] => 83
)
[3] => Array
(
[November 2012] => 72
)
[4] => Array
(
[November 2012] => 47
)
[5] => Array
(
[December 2012] => 93
)
[6] => Array
(
[November 2012] => 79
)
[7] => Array
(
[October 2012] => 70
)
[8] => Array
(
[November 2012] => 75
)
[9] => Array
(
[October 2012] => 59
)
[10] => Array
(
[December 2012] => 67
)
)
I'm able to get the total for each month using:
foreach($ary as $array)
{
foreach($array as $month=>$cent)
{
if(isset($abc[$month])) // prevent index warning
{
$abc[$month] += $cent;
// tried using $abc[$month] = $abc[$month]/2 but wrong values were returned
}
else
{
$abc[$month] = $cent;
}
}
}
This is resulting in
Array
(
[December 2012] => 2195
[November 2012] => 2159
[October 2012] => 1631
)
But I'm unable to find a way to find the average value for each month. In my case, there are 31 instances of December 2012, 31 instances of November 2012 and 25 instances of October 2012. Thus, I need to get hold of these 31, 31, and 25 values so that I can divide a month by that number.
I'm thinking something must be done inside if(isset($abc[$month])) loop to capture but haven't been successful so far. Is there any other way to get the average?
PS : I can't hardcode the month's name (October, November, December) for comparison purposes. They keep changing at regular intervals.
$eachMonth = array();
foreach($ary as $array)
{
foreach($array as $month=>$cent)
{
$eachMonth[$month][] = $cent;
if(isset($abc[$month])) // prevent index warning
{
$abc[$month] += $cent
}
else
{
$abc[$month] = $cent;
}
}
}
then for each month you can calculate average:
foreach( $eachMonth as $month => $values)
{
echo $month.' : '.$abc[$month] / count($values);
}
try this :
$your_array = array(array("December 2012" => 58),
array("December 2012" => 58)
);
$res = array();
foreach($your_array as $val){
$res[key($val)][] = $val[key($val)];
}
foreach($res as $k=>&$v){
$v = array_sum($v)/count($v);
}
echo "<pre>";
print_r($res);

Find missing numbers in array

I'm trying to find each missing number in an array like the following.
Array (
[0] => 1 [1] => 2 [2] => 3 [3] => 4 [4] => 5 [5] => 6 [6] => 7 [7] => 8
[8] => 9 [9] => 10 [10] => 11 [11] => 12 [12] => 13 [13] => 14 [14] => 15
[15] => 16 [16] => 17 [17] => 18 [18] => 19 [19] => 20 [20] => 21 [21] => 22
[22] => 23 [23] => 24 [24] => 25 [25] => 26 [26] => 27 [27] => 28 [28] => 29
[29] => 30 [30] => 31 [31] => 32 [32] => 33 [33] => 34 [34] => 35 [35] => 36
[36] => 37 [37] => 38 [38] => 39 [39] => 40 [40] => 41 [41] => 42 [42] => 43
[43] => 44 [44] => 45 [45] => 46 [46] => 47 [47] => 48 [48] => 49 [49] => 50
[50] => 51 [51] => 52 [52] => 53 [53] => 54 [54] => 55 [55] => 56 [56] => 57
[57] => 58 [58] => 59 [59] => 60 [60] => 61 [61] => 62 [62] => 63 [63] => 64
[64] => 67 [65] => 68 [66] => 69
)
The numbers 65,66 are missing in this particular array.
My question how do I figure out which numbers are missing with the help of PHP. Specifically what I need to find out is the lowest missing number.
Why: Because then I can assign that number to a member as an id.
You can make use of array_diff and range functions as:
// given array. 3 and 6 are missing.
$arr1 = array(1,2,4,5,7);
// construct a new array:1,2....max(given array).
$arr2 = range(1,max($arr1));
// use array_diff to get the missing elements
$missing = array_diff($arr2,$arr1); // (3,6)
I'm assuming the number is the element, not the key, of the array. I'm also assuming that the numbers start from 1, not 0.
$Expected = 1;
foreach ($InputArray as $Key => $Number)
{
if ($Expected != $Number)
{
break;
}
$Expected++;
}
echo $Number;
For big sorted arrays of unique numbers, you can binary search the array for either the lowest or highest unused number. Cost=Log2N. Example: 65536 items can be searched in 16 loops since
if ( arr[hi] - arr[lo] > hi - lo )
... there are unused numbers in that range ...
So (I don't know PHP, but it can be translated...):
lo = first entry index
hi = last entry index
if ( arr[hi] - arr[lo] == hi - lo )
return arr[hi]+1; // no gaps so return highest + 1
do
{
mid = (lo + hi) / 2;
if ( arr[mid] - arr[lo] > mid - lo ) // there is a gap in the bottom half somewhere
hi = mid; // search the bottom half
else
lo = mid; // search the top half
} while ( hi > lo + 1 ); // search until 2 left
return arr[lo]+1;
If given input is not in sorted order and size of input is very large then we can use following logic in any programming language:
Algorithm
bring smaller chunk into memory from large input
initialize three variables say min = 0, max = 0 and missingIds = []
scan smaller chunked input from left to right
if scannedValue found in missingIds
then,
pop scannedValue from missingIds
go to next value;
If scanned value is near to min
then,
find all the missing numbers between scannedValue and min, push into missingIds
min = scannedValue;
Else if scanned value is near to max
then,
find all the missing numbers between scannedValue and max, push into missingIds
max = scannedValue;
repeat above steps until large input scanned from left to right
Example in PHP
<?php
$largeInput = [40,41,42,43,44,45,1,2,3,4,5,6,7,8,9,10,11,12,13,14,35,36,37,38,39,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,67,68,69,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34];
$missingIds = [];
$min = 0;
$max = 0;
$chunkSize = 10;
$chunkNo = 0;
$currentInput = array_slice($largeInput, $chunkNo, $chunkSize);
while(count($currentInput) > 0) {
foreach($currentInput as $id) {
if(in_array($id,$missingIds)) {
$missingIds = array_diff($missingIds,[$id]);
continue;
}
if($id <= $min) {
$distMin = $min - $id;
if($distMin > 2) {
$tempArr = range($id+1,$min-1);
$missingIds = array_merge($missingIds, $tempArr);
$tempArr = [];
} else if ($distMin > 1) {
$tempArr = [$id+1];
$missingIds = array_merge($missingIds, $tempArr);
$tempArr = [];
}
$min = $id;
} else if ($id >= $max){
$distMax = $id - $max;
if($distMax > 2) {
$tempArr = range($max+1,$id-1);
$missingIds = array_merge($missingIds, $tempArr);
$tempArr = [];
} else if ($distMax > 1) {
$tempArr = [$max+1];
$missingIds = array_merge($missingIds, $tempArr);
$tempArr = [];
}
$max = $id;
}
}
$chunkNo++;
$currentInput = array_slice($largeInput, $chunkNo, $chunkSize);
}
print_r($missingIds);
//$idArrayMissing = array([0] => 1, [1] => 2, [2] => 4, [3] => 5, [4] => 6, [5] => 7);
$idArrayMissing = array(1, 2, 4, 5, 6, 7);
//$idArrayFull = array([0] => 1, [1] => 2, [2] => 3, [3] => 4, [4] => 5, [5] => 6);
$idArrayFull = array(1, 2, 3, 4, 5, 6);
function gap($arr)
{
while (list($k, $v) = each($arr))
if ($k != ($v-1))
return $k;
return -1;
}
print "ok:" . gap($idArrayMissing) . "<br/>\n";
print "full:" . gap($idArrayFull) . "<br/>\n";
The return of the gap function can be 2 values:
-1 could indicate that the array has been traversed and there are no free slots or
$k+1 which could indicate that the first free slot is on the end of the array.
It can also be done easily by using in_array() function like this:
// lets say $InputArray has all the data
// lets declare a variable which we will search inside the $InputArray array and lets initialize it with either 0 or 1 or with the minimum value found inside $InputArray
$start_counting = 1;
$max_value = count($InputArray);
if (!(in_array($start_counting, $InputArray)))
{
echo "Value: ".$start_counting." is missing!"."<br>" ;
}
else{
if($start_counting <= $max_value -1)
{$start_counting++;}
}
else if($start_counting > $max_value -1)
{
echo "All missing numbers printed!"
}
}

Categories