I am trying to make a Vigenère table using PHP. My goal is to make a big array with 26 smaller arrays in it like this:
$bigarray = [['a'-'z']['b'-'a']...['y'-'x']['z'-'y']];
I'm thinking of making the first array using the range() function, append that in the big array, then use a for loop to take the first letter, place that letter at the end and make that array append in a big array x25
$letterarray = range('a','z');
array_merge($bigarray, $firstarray);
for ($idx = 0; $idx < 26; $idx++) {
$letterarray = /* Take first letter from $letterarray, put that letter in the end. */
$bigarray = /* Put the $letterarray into the $bigarray. */
I don't know if I need to use the array_splice() or array_slice() function. I also don't know how to put the small array into the big array while keeping the 'array in array' form, because array_merge() just shoves every value into one array.
Your approach is solid. To execute, you just need to copy the previous array, and then use array_shift and array_push to "cycle" it.
$bigarray = [range('a','z')];
for( $i=1; $i<26; $i++) {
// $i=1 because we already have the first one.
$copy = $bigarray[$i-1]; // get most recent entry
array_push($copy,array_shift($copy));
$bigarray[$i] = $copy;
}
Thanks for your comment, after I wrote this thread I figured out a way myself.
$bigarray = array();
$alphas = range('a', 'z');
$bigarray[0] = $alphas;
for ($idx = 1; $idx <= 25; $idx++) {
$firstletter = $alphas[0];
$alphas = array_slice($alphas,1);
array_push($alphas, $firstletter);
$bigarray[$idx] = $alphas;
}
It stores the first letter of the [a-z] array ($alphas) in the variable $firstletter, slices the $alphas array and pushes the element in the $firstletter varible at the end and stores the new array [b-a] into the $bigarray.
The neat thing is that array_slice just changes the indices automatically.
Thanks for the comment :)
-Ed
Related
What's an efficient way to pop the last n elements in an array?
Here's one:
$arr = range(1,10);
$n = 2;
$popped_array = array();
for ($i=0; $i < $n; $i++) {
$popped_array[] = array_pop($arr);
}
print_r($popped_array); // returns array(10,9);
Is there a more efficient way?
Use array_splice():
If you're trying to remove the last n elements, use the following function:
function array_pop_n(array $arr, $n) {
return array_splice($arr, 0, -$n);
}
Demo
If you want to retrieve only the last n elements, then you can use the following function:
function array_pop_n(array $arr, $n) {
array_splice($arr,0,-$n);
return $arr;
}
Demo
It's important to note, looking at the other answers, that array_slice will leave the original array alone, so it will still contain the elements at the end, and array_splice will mutate the original array, removing the elements at the beginning (though in the example given, the function creates a copy, so the original array still would contain all elements). If you want something that literally mimics array_pop (and you don't require the order to be reversed, as it is in your OP), then do the following.
$arr = range(1, 10);
$n = 2;
$popped_array = array_slice($arr, -$n);
$arr = array_slice($arr, 0, -$n);
print_r($popped_array); // returns array(9,10);
print_r($arr); // returns array(1,2,3,4,5,6,7,8);
If you require $popped_array to be reversed, array_reverse it, or just pop it like your original example, it's efficient enough as is and much more direct.
Why not use array_slice. You can give a start and a length, so if you do 2 from the end you will get the last two items in the array:
$arr = range(1,10);
$n = 2;
$start = count($arr) - $n;
print_r(array_slice($arr, $start, $n));
Thanks for the array_slice comments. I don't know why that didn't immediately come to mind.
It looks (to me) like the easiest way is:
$arr = range(1,10);
$n = 2;
$popped_array = array_slice($arr,-$n);
print_r($popped_array); // returns array(10,9);
I have an array that I want to rename so that the values are stored depending on what number the for loop is on. I tried something like this but its giving me an error.
for ($i =0;$i<4;$i++){
$array.$i = array();
push stuff into array;
}
So at the next iteration the array is called array1, then array2 and so forth. What is the best way to do this.
To literally answer your question:
$arrayName = 'array' . $i;
$$arrayName = array();
$$arrayName[] = ...
What you really want is a multidimensional array though:
$array[$i] = array();
$array[$i][] = ...;
You want to use variable variables, in which the double dollar sign indicates that the name of the variable is taken from a variable.
$varname = "array";
for ($i =0;$i<4;$i++){
$newvarname = $varname . $i
$$newvarname = new array()
push stuff into array;
}
I would add that in these cases, a simpler solution is often to use an array in which the desired variable names are indices. So instead of creating $array1, $array2, and so forth, you'd have:
$arrays = array (
'array1' => array(stuff),
'array2' => array(stuff),
'array3' => array(stuff),
'array4' => array(stuff)
}
At least, I find it easier to keep track of.
You should be able to reference the array using the $$ notation for variable variables (see: http://www.php.net/manual/en/language.variables.variable.php).
So, something like this should work (untested):
for ($i =0;$i<4;$i++){
$thisArrayName = 'array'.$i;
$$thisArrayName = array();
push stuff into array;
}
You need array of array
for ($i =0;$i<4;$i++){
$array[$i] = array();
push stuff into array;
}
Please tell me which is the best way to unset middle element of associative array in PHP?
Suppose I have an array of 10,000 elements and I want to remove middle element of that array, which is efficient way to remove middle element?
$temp = array('name1'=>'value1','name2'=>'value2',...,'name10000'=>'value10000');
$middleElem = ceil(count($temp) / 2);
$i = 0;
foreach ($temp as $key=>$val) {
if ($i == $middleElem) {
unset($temp[$key]);
break;
}
$i++;
}
Is above code efficient way?
Considering $array is your array, this code remove the middle element if it has odd number of elements. If its event it'll remove the first of 2 middle elements.
$i = round(count($array)/2) - 1;
$keys = array_keys($array);
unset ($array[$keys[$i]]);
Test Result: http://ideone.com/wFEM2
The thing you have to figure out is what you want to do when you have an array with an even number of elements. What element do you want to get then?
The above code picks the 'lower' element, the code could easily be edited to make it pick the 'higher' element. The only thing you have to check is (what all others answers failed to do) what happens if you have three elements. It doesn;t pick the middle element, but the last. So you would have to add a check for that then.
$temp = Array("name1"=>"value1","name2"=>"value2",...,"name10000"=>"value10000");
$middleElem = ceil(count($temp)/2);
$keys = array_keys($temp);
$middleKey = $keys[$middleElem];
unset($temp[$middleKey]);
There ^_^
I think it's a proper way to do it. Try this:
array_remove_at( $temp, ceil(count($temp) / 2) - 1);
function array_remove_at(&$array, $index){
if (array_key_exists($index, $array)) {
array_splice($array, $index, 1);
}
}
You can find the size of the array, divide that number by two and then proceed to remove the element. Not sure about the performance isssues about that though
Firstly, I wouldn't worry too much about what is the most efficient way at this point. You're much better off coding for how easy the code is to read, debug and change. Micro-optimisations like this rarely produce great results (as they're often not the biggest bottlenecks).
Having said that, if you want a solution that is easy to read, then how about using array_splice.
$temp = array('name1'=>'value1','name2'=>'value2',...,'name10000'=>'value10000');
$middleElem = ceil(count($temp) / 2);
array_splice( $temp, $middleElem, 1 );
I would take it that the following code is more efficient, because you don't have to execute it in a loop. I generally follow the same pattern as Kolink, but my version checks if there actually is a "middle element". Works on all types of arrays, I think.
<?php
for( $i = 0; $i <= 9; $i ++ ) {
$temp['name'.$i] = 'value'.$i;
}
if( ( $count = count( $temp ) ) % 2 === 0 ) {
/** Only on uneven arrays. */
array_splice( $temp, ( ceil( $count ) / 2 ), 1 );
}
var_dump( $temp );
EDIT: Thavarith seems to be right; array_splice is much faster than simply unsetting the value. Plus, you get the added benefit of not having to use array_keys, as you already now at what $offset the middle is.
Proper way seems to be:
unset(arr[id]);
arr = array_values(arr);
For first removing element at index id and then re-indexing the array arr properly.
unset($myArray[key])
since your array is associative, you can drop any element easily this way
$index = 0;
foreach ($sxml->entry as $entry) {
$array + variable index number here = array('title' => $title);
$index++;
}
I'm trying to change an array name depending on my index count. Is it possible to change variable name (ie. $array1, $array2 $array3 etc.) in the loop?
Edit:
After the loop has finished, I will generate a number number (depending on the count of $index) and then use this array... probably it's a stupid way of accomplishing what Im trying to do, but I don't have a better idea.
You might want to try this instead:
$index = 0;
$arrays = array();
foreach ($sxml->entry as $entry) {
$arrays[$index] = array('title' => $title);
$index++;
}
While it is technically possible to do what you are asking, using an array of arrays will probably work better from you.
This type of indexing is exactly what arrays are designed for, you have a lot of items and want to be able to refer to them by number.
Unless you have a very specific reason to use the name of the variable to represent it's number you will probably have a much simpler time using it's index in the outer array.
Yes you can user an associate array. Generating a string dynamically based on the iteration number and using that as a key in the array.
You can use variable variables. php.net
PHP supports Variable variables:
$num = 1;
$array_name = 'array' . $num;
$$array_name = array(1,2,3);
print_r($array1);
http://php.net/manual/en/language.variables.variable.php
I need to merge several arrays into a single array. The best way to describe what I'm looking for is "interleaving" the arrays into a single array.
For example take item one from array #1 and append to the final array. Get item one from array #2 and append to the final array. Get item two from array #1 and append...etc.
The final array would look something like this:
array#1.element#1
array#2.element#1
.
.
.
The "kicker" is that the individual arrays can be of various lengths.
Is there a better data structure to use?
for example,
function array_zip_merge() {
$output = array();
// The loop incrementer takes each array out of the loop as it gets emptied by array_shift().
for ($args = func_get_args(); count($args); $args = array_filter($args)) {
// &$arg allows array_shift() to change the original.
foreach ($args as &$arg) {
$output[] = array_shift($arg);
}
}
return $output;
}
// test
$a = range(1, 10);
$b = range('a', 'f');
$c = range('A', 'B');
echo implode('', array_zip_merge($a, $b, $c)); // prints 1aA2bB3c4d5e6f78910
If the arrays only have numeric keys, here's a simple solution:
$longest = max( count($arr1), count($arr2) );
$final = array();
for ( $i = 0; $i < $longest; $i++ )
{
if ( isset( $arr1[$i] ) )
$final[] = $arr1[$i];
if ( isset( $arr2[$i] ) )
$final[] = $arr2[$i];
}
If you have named keys you can use the array_keys function for each array and loop over the array of keys instead.
If you want more than two arrays (or variable number of arrays) then you might be able to use a nested loop (though I think you'd need to have $arr[0] and $arr[1] as the individual arrays).
I would just use array_merge(), but that obviously depends on what exactly you do.
This would append those arrays to each other, while elements would only be replaced when they have the same non-numerical key. And that might not be a problem for you, or it might be possible to be solved because of attribute order, since the contents of the first arrays' elements will be overwritten by the later ones.
If you have n arrays, you could use a SortedList, and use arrayIndex * n + arrayNumber as a sort index.