How do I delete the whole line from an array? When the delete-button is pressed it should delete the whole line.
my array looks like that:
$liste[0][0] = email-user1
$liste[0][1]= password-user1
$liste[1][0] = email-user2
$liste[1][1]= password-user2
So if I delete the user one, the user2 should just take the place from user1(which should just disappear).
if (isset($_GET['delete'])){
$id=key($_GET['delete']);
for ($i = 0; $i < count($liste); $i++){
if ("$i"=="$id"){
unset($liste[$id][0]);
unset($liste[$id][1]);
unset($liste[$id][2]);
}
else{
}
}
update
I'm using array_splice($liste, $id, 1); now but everytime I try to save it to the file I get an error: implode(): Invalid arguments passed. For saving it to the file, I use the following function:
function saveDataToFile($fileName, $liste){
$file=fopen($fileName,"w");
for ($i = 0; $i < count($liste); $i++) {
$zArray=$liste[$i];
$zeile=implode("|", $zArray);
if(strlen($zeile) > 0){
$zeile=$zeile."\r\n";
fwrite($file, $zeile);
}
}
fclose($datei);
}
Try the below code:
$liste[0][0] = "email-user1";
$liste[0][1]= "password-user1";
$liste[1][0] = "email-user2";
$liste[1][1]= "password-user2";
$liste[2][0] = "email-user3";
$liste[2][1]= "password-user3";
unset($liste[1]); // say you want to delete this row
$new_arr = $liste;
unset($liste);
$i=0;
foreach($new_arr as $value){
$liste[$i] = $value;
$i++;
}
You can use array_splice() method:
array_splice($liste, $id, 1);
$liste[0][0], $liste[0][1] and $liste[0][2] are in real nothing else than a value array(value, value, value) (the inner array) which is assigned to $liste[0] (the outer array)
unsetting this (outer) array value $liste[0] is enough:
unset($liste[$id]);
If you care about the keys of this array (I see you loop from 0..n), you need to reindex your array using:
$liste = array_values($liste);
This will make your array behaving more like arrays normally do in other programming languages
Good practice is to use foreach instead of for. In this case you don't need to reindex:
for ($liste as $key=>$value){
if ("$key"=="$id"){
unset($liste[$key]);
}
But anyway you don't have to loop through an array just for finding a key. It's enough doing this:
if (isset($liste[$id])) { /* optional: check if the key exists */ }
unset($liste[$id]);
Related
I'm attempting to to remove random elements from a collection while iterating through a for loop. The idea is that each time it goes through the for loop, the items in the collection available doesn't include items found and removed in previous iterations. I've attempted to use forget on the initial collection, but i'm still finding doubles in the results. Any help would be appreciated, thanks!
$data = SomeModel::get();
for($i = 1; $i <= $max; $i++) {
$random = $data->random($numberToPick);
foreach($random as $option) {
$data->forget($option->id);
}
}
I dd($data) at the end, and do indeed see the items selected are removed from the final collection, but as mentioned, i'm still getting some randoms that have keys matching previous iterations.
The problem here is that forget will remove the item by its index. You are giving as argument the id of the object inside the collection, but its index is not the same as the id.
Try this:
$data = SomeModel::get()->keyBy('id');
for($i = 1; $i <= $max; $i++) {
$random = $data->random($numberToPick);
foreach($random as $option) {
$data->forget($option->id);
}
}
I am looking for a way to create new arrays in a loop. Not the values, but the array variables. So far, it looks like it's impossible or complicated, or maybe I just haven't found the right way to do it.
For example, I have a dynamic amount of values I need to append to arrays. Let's say it will be 200 000 values. I cannot assign all of these values to one array, for memory reasons on server, just skip this part.
I can assign a maximum amount of 50 000 values per one array. This means, I will need to create 4 arrays to fit all the values in different arrays. But next time, I will not know how many values I need to process.
Is there a way to generate a required amount of arrays based on fixed capacity of each array and an amount of values? Or an array must be declared manually and there is no workaround?
What I am trying to achieve is this:
$required_number_of_arrays = ceil(count($data)/50000);
for ($i = 1;$i <= $required_number_of_arrays;$i++) {
$new_array$i = array();
foreach ($data as $val) {
$new_array$i[] = $val;
}
}
// Created arrays: $new_array1, $new_array2, $new_array3
A possible way to do is to extend ArrayObject. You can build in limitation of how many values may be assigned, this means you need to build a class instead of $new_array$i = array();
However it might be better to look into generators, but Scuzzy beat me to that punchline.
The concept of generators is that with each yield, the previous reference is inaccessible unless you loop over it again. It will be in a way, overwritten unlike in arrays, where you can always traverse over previous indexes using $data[4].
This means you need to process the data directly. Storing the yielded data into a new array will negate its effects.
Fetching huge amounts of data is no issue with generators but one should know the concept of them before using them.
Based on your comments, it sounds like you don't need separate array variables. You can reuse the same one. When it gets to the max size, do your processing and reinitialize it:
$max_array_size = 50000;
$n = 1;
$new_array = [];
foreach ($data as $val) {
$new_array[] = $val;
if ($max_array_size == $n++) {
// process $new_array however you need to, then empty it
$new_array = [];
$n = 1;
}
}
if ($new_array) {
// process the remainder if the last bit is less than max size
}
You could create an array and use extract() to get variables from this array:
$required_number_of_arrays = ceil($data/50000);
$new_arrays = array();
for ($i = 1;$i <= $required_number_of_arrays;$i++) {
$new_arrays["new_array$i"] = $data;
}
extract($new_arrays);
print_r($new_array1);
print_r($new_array2);
//...
I think in your case you have to create an array that holds all your generated arrays insight.
so first declare a variable before the loop.
$global_array = [];
insight the loop you can generate the name and fill that array.
$global_array["new_array$i"] = $val;
After the loop you can work with that array. But i think in the end that won't fix your memory limit problem. If fill 5 array with 200k entries it should be the same as filling one array of 200k the amount of data is the same. So it's possible that you run in both ways over the memory limit. If you can't define the limit it could be a problem.
ini_set('memory_limit', '-1');
So you can only prevent that problem in processing your values directly without saving something in an array. For example if you run a db query and process the values directly and save only the result.
You can try something like this:
foreach ($data as $key => $val) {
$new_array$i[] = $val;
unset($data[$key]);
}
Then your value is stored in a new array and you delete the value of the original data array. After 50k you have to create a new one.
Easier way use array_chunk to split your array into parts.
https://secure.php.net/manual/en/function.array-chunk.php
There's non need for multiple variables. If you want to process your data in chunks, so that you don't fill up memory, reuse the same variable. The previous contents of the variable will be garbage collected when you reassign it.
$chunk_size = 50000;
$number_of_chunks = ceil($data_size/$chunk_size);
for ($i = 0; $i < $data_size; $i += $chunk_size) {
$new_array = array();
foreach ($j = $i * $chunk_size; $j < min($j + chunk_size, $data_size); $j++) {
$new_array[] = get_data_item($j);
}
}
$new_array[$i] serves the same purpose as your proposed $new_array$i.
You could do something like this:
$required_number_of_arrays = ceil(count($data)/50000);
for ($i = 1;$i <= $required_number_of_arrays;$i++) {
$array_name = "new_array_$i";
$$array_name = [];
foreach ($data as $val) {
${$array_name}[] = $val;
}
}
So I have 2 files. In file 1 I have a table and there I randomly select some fields and store (store in session) them in an array of 2D arrays. When I click on the cell I send this data to my file 2 where I want to check if I clicked on a randomly selected array or not and if I did, I want to remove this 2D array from an main array.
But as soon as I click on one of the selected arrays, the array crashes.
File 1 PHP stuff immportant for this:
session_start();
$_SESSION['arrays'] = $stack ;
File 2 PHP:
session_start();
if (isset($_SESSION['arrays'])) {
$stack = $_SESSION['arrays'];
for ($i = 0; $i< count($stack);$i++){
if($cooridnates == $stack[$i]){
unset($stack[$i]);
array_values($stack);
$i--;
$Result = true;
break;
}
}
$_SESSION['arrays'] = $stack ;
I am suspecting the error might be in 2 things:
count($stack) used, but I don't believe this is the main reason.
The way I store session.
I have tried using manuals from W3Schools and official PHP website and also SOF, but with no use.
But still, I am not sure if the array_values() and unset() is working correctly since the thing chrashes and I can't test it correctly.
I would appreciate any tips.
You need to assign the result of array_values($stack); back to the $stack variable.
$stack = array_values($stack);
There's also no need to use $i-- when you do this, since you're breaking out of the loop after you find a match.
Instead of a loop, you can use array_search():
$pos = array_search($coordinates, $stack);
if ($pos !=== false) {
unset $stack[$pos];
$Result = true;
$stack = array_values($stack);
$_SESSION['arrays'] = $stack;
}
you can do this like that by using foreach loop:
session_start();
if (!empty($_SESSION['arrays'])) {
foreach( $_SESSION['arrays'] as $key => $val){
if($cooridnates == $val){
unset($_SESSION['arrays'][$key]); // if you want this removed value then assign it a variable before unsetting the array
$Result = true;
break;
}
}
}
I have a button next to all my 'shop items' that can remove one of the shop item, however i need it to just remove one, and not rid the entire array of the number, i thought this was possible by using a break statement when i found the number i want to remove, but it removes all of the numbers.
if (isset($_GET['remove']) && isset($_SESSION['shopitems'])) {
if (in_array($_GET['remove'], $_SESSION['shopitems'])) {
for ($i = 0; $i < sizeof($_SESSION['shopitems']); $i++) {
if ($_SESSION['shopitems'][$i] == $_GET['remove']) {
$shopArray = $_SESSION['shopitems'];
if(sizeof($shopArray) == 1) {
$_SESSION['shopitems'] = null;
$_SESSION['added'] = null;
} else {
array_splice($shopArray, $i, $i);
$_SESSION['shopitems'] = $shopArray;
}
break;
}
}
}
}
Here i check if the URL contains the remove variable and the session is set, once i have done this, i check if the array contains the number that is put in the URL, if so i'll start a for loop and check if the key index of the session shop items is equal to the URL variable, if so i want to remove it, however if i use array_splice, suddenly they are all gone, is this because of the function i am using? Or is the break not executing correctly?
Why don't you try array_search() and unset()? It's easier, have a look at the code below and adapt it to your situation:
$array = [1, 5, 6, 12];
$wantToRemove = 5;
$key = array_search($wantToRemove, $array);
unset($array[$key]);
var_dump($array);
You can format your $_SESSION['shopitems'] like this :
$_SESSION['shopitems'] = array (
"item_id" => "item_info",
"item2_id" => "item2_info",
...
)
and do unset($_SESSION['shopitems'][$_GET['remove']]).
Your code could be :
if (isset($_GET['remove']) && isset($_SESSION['shopitems']))
if (isset($_SESSION['shopitems'][$_GET['remove']]))
unset($_SESSION['shopitems'][$_GET['remove']])
I can't seem to figure out the best way to do this. I have a RecursiveIteratorIterator.
$info = new RecursiveIteratorIterator(
new GroupIterator($X), # This is a class that implements RecursiveIterator
RecursiveIteratorIterator::SELF_FIRST
);
Note: GroupIterator is a class that handles our custom formatted data
When I loop through it, I get exactly what I expect.
foreach($info as $data){
echo $info->getDepth().'-'.$data."\n";
}
The output is:
0-a
1-b
2-c
2-d
1-e
2-f
0-g
1-h
2-i
This is correct, so far. Now, what I want is to flatten the parents and children into a single array. I want one row for each max-depth child. The output I am trying to get is:
0-a 1-b 2-c
0-a 1-b 2-d
0-a 1-e 2-f
0-g 1-h 2-i
I can't figure out how to do this. Each iteration over the loop gives me another row, how can I combine the rows together that I want?
I managed to figure it out. #ComFreek pointed me in the right direction. Instead of using a counter, I used the current depth to check when I hit the lowest child, then I added the data to the final array, otherwise I added it to a temp array.
$finalArray = array();
$maxDepth = 2;
foreach($info as $data){
$currentDepth = $info->getDepth();
// Reset values for next parent
if($currentDepth === 0){
$currentRow = array();
}
// Add values for this depth
$currentRow[$currentDepth] = $data;
// When at lowest child, add to final array
if($currentDepth === $maxDepth){
$finalArray[] = $currentRow;
}
}
Try adding a counter variable:
// rowNr loops through 0, 1, 2
$rowNr = 0;
$curData = [];
$outputData = [];
foreach($info as $data){
// got last element, add the temp data to the actual array
// and reset temp array and counter
if ($rowNr == 2) {
$outputData[] = $curData;
$curData = [];
$rowNr == 0;
}
else {
// save temp data
$curData[] = $info->getDepth() . '-' . $data;
}
$rowNr++;
}