Array is skipping some value indices - php

I'm trying to iterate through an array using for loop. However, the indices of the values of the array I'm working is not properly structured. This means that I can find an element at index number 8, index number 9 there's no element and the next element after 8 is at index number 11. Example:
array (size=4951)
8 => string '9,taobao.com
' (length=14)
11 => string '10,linkedin.com
' (length=17)
12 => string '11,amazon.com
' (length=15)
19 => string '12,live.com
' (length=13)
My question is, how can I make it so that the array doesn't skip indices like this? So that when I try to iterate through the array, it will go through index 8 where it will find 9,taobao.com and then on index 9 it would find 10,linkedin.com. Any suggestion will be greatly appreciated!

Use array_values:
$arr = array_values($arr);
It will rearrenge all keys, starting from 0

Why do not use a foreach loop with key, value (if you need the key)?
foreach($array as $key => $value) {
// Treatment.
}

Use a combination of for and isset :
for ($i = $idx_start, $len = count($array); $i < $len; ++$i) {
if (isset($array[$i])) {
// Do your stuff
}
}

You can re-index the array using the following function.
$reindexed_array = array_values(array_filter($array));
Hope it answers your question.

Related

Fatal error: Allowed memory size exhausted while looping through a 14 element long single-character-array

I have a simple string. I need to produce an output Array such that the order of every 2 consecutive characters is reversed.
Input string is 14f05000034e69 and I need the following output Array [4, 1, 0, f, 0, 5, 0, 0, 4, 3, 6, e, 9, 6].
Here is my PHP code:
$myString = "14f05000034e69";
$myStringArray = str_split($myString);
$newArray = array();
for ($index=0; $index<count($myStringArray)-1; $index+2) {
$newArray[] = $myStringArray[$index+1];
$newArray[] = $myStringArray[$index];
}
print_r($newArray);
And it is giving me
Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 134217736 bytes) in /var/www/html/test.php on line 8
The question is why and how do I fix it?
<?php
$myString = "14f05000034e69";
$myStringArray = str_split($myString);
$i=0;
foreach($myStringArray as $row){
if(array_key_exists($i,$myStringArray)) {
$newArray[$i] = $myStringArray[$i + 1];
$newArray[$i + 1] = $myStringArray[$i];
$i = $i + 2;
}
}
echo '<pre>';
print_r($newArray);
I found a workaround in a bit "dirty" way but i managed to do what you asked.
Basically i split the string like you did but i play with the new array positions around and push in my new array the positions that i want to that's why i used a counter for that.
The output is:
Array
(
[0] => 4
[1] => 1
[2] => 0
[3] => f
[4] => 0
[5] => 5
[6] => 0
[7] => 0
[8] => 3
[9] => 0
[10] => e
[11] => 4
[12] => 9
[13] => 6
)
Basically i thought that i need to loop the array by two but every time i loop i need to handle 2 array positions and then the next two.
So that led me to handle my $new_array in a way that i push at the same time data in the current position i am and in the next position, that's why the counter $i+1 is used to handle array position.
If i did not use it there and used simple $newArray[] it would put the data in my current position and overwrite it again in the second step and also i could not move my array pointer to positions 1,3,5,6 etc etc that's why i am "forcing" it to use my $i counter so i keep pointing every after position.
My $i counter is set at the end of each loop to move with step 2.
The shortest alternative I could come up with is to use some of the array methods instead...
$myString = "14f05000034e69";
$out = str_split(implode(array_map ('strrev', str_split($myString, 2))));
print_r( $out );
This uses str_split() to split it into 2 char chunks, then uses array_map() and strrev() to reverse each item and then implode() to put them all back again.
The outer call to str_split() just splits the result back down to 1 char elements in an array for the output (miss this off if you just need the string itself)
In my opinion, the str_split is redundant in this operation, strings can be iterated through as of arrays, like this:
$myString = "14f05000034e69";
$newArray = array();
for ($index=0; $index<strlen($myString)-1; $index+=2)
{
$newArray[] = $myString[$index+1];
$newArray[] = $myString[$index];
}
print_r($newArray);
But yeah, as said before, just missing += in the for loop.
I made a small test on regex to see if it could be done, works as a charm. But of course, I only deliver a string in this case. :)
$myString = "14f05000034e69";
$test = preg_replace('/(.)(.)/', '$2$1', $myString);
echo $test;
This is the most elegant solution I could come up with.
Code tested here: https://3v4l.org/mtdca
And for the regex: https://3v4l.org/nI4UP
An answer has already been marked as the solution an many other answers too however I think this can help to know that we can achieve the inversion in the string itself and then split it.If an array is not needed we can just keep the string.This way we use less memory i think:
$myString = "14f05000034e69";
$length=strlen($myString);
for ($index=-1, $length=$length%2==0?$length-1:$length-2; $index<$length-1; $index+=2) {
$tmp=$myString[$index+1];
$myString[$index+1]=$myString[$index+2];
$myString[$index+2]=$tmp;
}
print_r(str_split($myString));// return an array
print_r($myString); //here a string
This can handle variable length of strings

Grouping in PHP using a character

I have an array like:
array{
0 => string 'B.E - ECE',
1 => string 'B.E - EEE',
2 => string 'Msc - Maths',
3 => string 'Msc - Social',
}
So how can I make the array into groups like:
B.E. => ECE, EEE
Msc => Maths,Social
?
I want to do it in PHP. Can anybody help me how to achieve it ?
So is your array split by the "-" character?
so it's Key - Value pairs split by commas?
Ok -
(edit: section removed to clarify answer)
Following conversation and some rearrangement of the question, a second try at a solution, with the above assumptions, try this:
$array = array {
0 => string 'B.E - ECE' (length=9)
1 => string 'B.E - EEE' (length=9)
2 => string 'Msc - Maths' (length=11)
3 => string 'Msc - Social' (length=12)
}
foreach ($array as $row){
$piece = explode("-",$row);
$key = $piece[0];
$newArray[$key][] = $piece[1];
unset($piece);
}
unset($row) ///tidy up
This will output two arrays each of two arrays:
$newArray[Msc] = array("Maths","Social");
$newArray[B.E] = array("ECE","EEE");
What I did was cause the Foreach loop to automatically add onto the array if the key exists with $newArray[$key][] so that the values are automatically collected by key, and the key is defined as the first half of the original array values.
Printing:
To print the result:
foreach($newArray as $key=>$newRow){
/// there are two rows in this case, [B.E] and [MSc]
print $key.":<br>";
print "<pre>";
///<pre> HTML tag makes output use linebreaks and spaces. neater.
print_r($newRow);
///alternatively use var_dump($newRow);
print "</pre>";
}
Alternatively if you wish to print a known named variable you can write:
print_r($newArray['B.E']);
Which will print all the data in that array. print_r is very useful.
what you want is php's explode. Not sure if this will give you the perfect answer but should give you an idea of what to do next.
$groupedArray = array();
foreach($array as $row){
$split = explode(" - ",$row);
$groupedArray[] = $split[0];
}
array_unique($groupedArray); //This will give you the two groupings
foreach($array as $row){
$split = explode(" - ",$row);
$pos = array_search($split[0],$groupedArray);
if($pos !== FALSE){
$groupedArray[$pos][] = $split[1];
}
}
This should give you a full formatted array called $groupedArray where $array is the array you already have.
Hope this helps!

PHP: How to delete all array elements after an index [duplicate]

This question already has answers here:
php - how to remove all elements of an array after one specified
(3 answers)
Closed 9 years ago.
Is it possible to delete all array elements after an index?
$myArrayInit = array(1=>red, 30=>orange, 25=>velvet, 45=>pink);
now some "magic"
$myArray = delIndex(30, $myArrayInit);
to get
$myArray = array(1=>red, 30=>orange);
due to the keys in $myArray are not successive, I don't see a chance for array_slice()
Please note : Keys have to be preserved! + I do only know the Offset Key!!
Without making use of loops.
<?php
$myArrayInit = [1 => 'red', 30 => 'orange', 25 => 'velvet', 45 => 'pink']; //<-- Your actual array
$offsetKey = 25; //<--- The offset you need to grab
//Lets do the code....
$n = array_keys($myArrayInit); //<---- Grab all the keys of your actual array and put in another array
$count = array_search($offsetKey, $n); //<--- Returns the position of the offset from this array using search
$new_arr = array_slice($myArrayInit, 0, $count + 1, true);//<--- Slice it with the 0 index as start and position+1 as the length parameter.
print_r($new_arr);
Output :
Array
(
[1] => red
[30] => orange
[25] => velvet
)
Try
$arr = array(1=>red, 30=>orange, 25=>velvet, 45=>pink);
$pos = array_search('30', array_keys($arr));
$arr= array_slice($arr,0,$pos+1,true);
echo "<pre>";
print_r($arr);
See demo
I'd iterate over the array up until you reach the key you want to truncate the array thereafter, and add those items to a new - temporary array, then set the existing array to null, then assign the temp array to the existing array.
This uses a flag value to determine your limit:
$myArrayInit = array(1=>'red', 30=>'orange', 25=>'velvet', 45=>'pink');
$new_array = delIndex(30,$myArrayInit);
function delIndex($limit,$array){
$limit_reached=false;
foreach($array as $ind=>$val){
if($limit_reached==true){
unset($array[$ind]);
}
if($ind==$limit){
$limit_reached=true;
}
}
return $array;
}
print_r($new_array);
Try this:
function delIndex($afterIndex, $array){
$flag = false;
foreach($array as $key=>$val){
if($flag == true)
unset($array[$key]);
if($key == $afterIndex)
$flag = true;
}
return $array;
}
This code is not tested

Setting a PHP array's value to 0 if its key does not exist as a value in another array

Is there any kind of function or quick process for comparing two arrays in PHP in a way that if the value of one array exists as a key in the second array, the second array maintains its key's value, otherwise that key's value gets set to 0.
For example,
$first_array = array('fred', 'george', 'susie');
$second_array = array(
'fred' => '21',
'george' => '13',
'mandy' => '31',
'susie' => '11'
);
After comparing the two, ideally my final array would be:
Fred > 21
George > 13
Mandy > 0
Susie > 11
Where Mandy was set to 0 because the key didn't exist as a value in the first array…..
I know it's probably kind of an odd thing to want to do! But any help would be great.
foreach ($second_array as $key=>$val) {
if (!in_array($key, $first_array))) {
$second_array[$key] = 0;
}
}
Although you may want to build the first array as a set so that the overall runtime will be O(N) instead of O(N^2).
foreach($second_array as $name => $age) {
if(in_array($name, $first_array) {
//whatever
}
else {
//set the value to zero
}
}
// get all keys of the second array that is not the value of the first array
$non_matches = array_diff(array_keys($second_array), $first_array);
// foreach of those keys, set their associated values to zero in the second array
foreach ($non_$matches as $match) {
$second_array[$match] = 0;
}
foreach is more readable, but you can also use the array functions:
array_merge($second_array,
array_fill_keys(array_diff(array_keys($second_array),
$first_array),
0));
# or
array_merge(
array_fill_keys(array_keys($second_array), 0),
array_intersect_key($second_array, array_flip($first_array)));
# or
function zero() {return 0;}
array_merge(
array_map('zero', $second_array),
array_intersect_key($second_array, array_flip($first_array)));

Convert this associative array to a string or single indexed array

I need to convert this array into a single dimensional indexed array or a string. Happy to discard the first key (0, 1) and just keep the values.
$security_check_whitelist = array
0 =>
array
'whitelisted_words' => string 'Happy' (length=8)
1 =>
array
'whitelisted_words' => string 'Sad' (length=5)
I tried array_values(), but it returned the exact same array structure.
This works:
$array_walker = 0;
$array_size = count($security_check_whitelist);
while($array_walker <= $array_size)
{
foreach($security_check_whitelist[$array_walker] as $security_check_whitelist_value)
{
$security_check[] = $security_check_whitelist_value;
}
$array_walker++;
}
But it returns:
Warning: Invalid argument supplied for
foreach()
How can I convert the associative array without receiving the warning message? Is there a better way?
foreach ($security_check_whitelist as &$item) {
$item = $item['whitelisted_words'];
}
Or simply:
$security_check_whitelist = array_map('current', $security_check_whitelist);
The problem here could be that you should only walk up to N-1, so $array_walker < $array_size.
So is "whitelisted_words" an array as well? If so, I think the following would work:
$single_dim_array = array();
foreach(array_values($security_check_whitelist) as $item) {
foreach($item['whitelisted_words'] as $word) {
$single_dim_array[] = $word;
}
}
Then the variable $single_dim_array contains all your whitelisted words.

Categories