Function is changing array from numeric to associative - php

This is supposed to take any rows where ing_name is duplicated, combine the eff_name fields and delete the duplicate but it also has the side effect of changing the array from numeric to associative. My ajax is expecting numeric array.
for($i=count($recipe)-1; $i>0; $i--) {
if($recipe[$i]['ing_name'] == $recipe[$i-1]['ing_name']) { //check for duplicate. **array must be sorted by ing_name**
$recipe[$i-1]['eff_name'] .= ', '.$recipe[$i]['eff_name']; //Combine eff_name of duplicates
$recipe[$i-1]['link'] = true;
unset($recipe[$i]); //remove duplicate index
}
}
examples: NUM, ASSOC
Source
EDIT: So i figured it must have something to do with unsetting the index so I did this and it seems to work ok:
$newRecipe = array();
foreach($recipe as $r) {
$newRecipe[] = $r;
}
New question, is there a better way?

unset works with named keys. You could use array_splice instead, or get a brand new array after the loop with array_values (but that would be ugly!).

array_values() Will return a numerically indexed array

Related

what should I use instead of array_unique in php?

I am getting duplicate data in an array and that data is storing in my DB. I am using array_unique to refine the duplicate data but it is not working. Please tell me is there any other way to make data unique and store in DB this way.
if (preg_match($keywords, $links[$i]->href)) {
if (filter_var($links[$i]->href, FILTER_VALIDATE_URL) !== false) {
array_push($mainNews, $links[$i]->href);
}
}
return (array_unique($mainNews));
Error I am getting:
Undefined array key 1 at C:\xampp\htdocs\pacra-crawlers\modules\crawlers\services\MainNewsRepository.php:46
for ($i = 0; $i < count($mainNewsLinks); $i++) {
$mainNews = new MainNews();
$mainNews->newspaper_id = $this->newspaperId;
$mainNews->sector_id = $sectorId;
$mainNews->url = $mainNewsLinks[$i];
$mainNews->save();
}
return ['status' => true];
}
C:\xampp\htdocs\pacra-crawlers\modules\crawlers\services\MainNewsRepository.php:46
Illuminate\Foundation\Bootstrap\HandleExceptions::handleError("Undefined array key 1", "C:\xampp\htdocs\pacra-crawlers\modules\crawlers\services\MainNewsRepo
sitory.php")
array_unique is working however although it is removing duplicates it is maintaining the same keys i.e.
If you had the following items in an array with
position/key value
0 a
1 a
2 b
array_unique would return
position/key value
0 a
2 b
which is why you are getting the Undefined array key when looping through the array based on the incrementing index $i.
Based on your sample you could use a foreach loop since you are only interested in the value eg
foreach($mainNewsLinks as $mainNewsLink) {
$mainNews = new MainNews();
$mainNews->newspaper_id = $this->newspaperId;
$mainNews->sector_id = $sectorId;
$mainNews->url = $mainNewsLink;
$mainNews->save();
}
If you would like to continue indexing or iterating through each element based on an index, you could use array_values in your return eg
return array_values(array_unique($mainNews));
from your function to reset the array keys to incrementing indexes

Store Get-Values from form in Array PHP

I'm trying to store the users's input via the method get in an array to store it and further process it without overwriting the initial get-value. But I dont know how.. do I have to store them in a database to do that? Or can I just push every input into an array?
I believe the following should work for you... This will take all the $_GETs that you supply and put them in a new array so you can modify them without affecting the original $_GET array.
if(is_array($_GET)){
$newArr = $_GET; // modify $newArr['postFieldName'] instead of $_GET['postFieldName'] to preserve original $_GET but have new array.
}
That solution there will dupe the $_GET array. $_GET is just an internal PHP array of data, as is $_POST. You could also loop through the GETs if you do not need ALL of the GETs in your new array... You would do this by setting up an accepted array of GETs so you only pull the ones you need (this should be done anyways, as randomly accepting GETs from a form can lead to some trouble if you are also using the GETs for database/sql functions or anything permission based).
if(is_array($_GET) && count($_GET) > 0){
$array = array();
$theseOnly = array("postName", "postName2");
foreach($_GET as $key => $value){
if(!isset($array[$key]) && in_array($key, $theseOnly)){ // only add to new array if they are in our $theseOnly array.
$array[$key] = $value;
}
}
print_r($array);
} else {
echo "No $_GET found.";
}
I would just add to what #Nerdi.org said.
Specifically the second part, instead of looping through the array you can use either array_intersect_key or array_diff_key
$theseOnly = array("postName", "postName2");
$get = array_intersect_key( $_GET, array_flip($theseOnly);
//Or
$get = array_diff_key( $_GET, array_flip($theseOnly);
array_intersect_key
array_intersect_key() returns an array containing all the entries of array1 which have keys that are present in all the arguments.
So this one returns only elements you put in $theseOnly
array_diff_key
Compares the keys from array1 against the keys from array2 and returns the difference. This function is like array_diff() except the comparison is done on the keys instead of the values.
So this one returns the opposite or only elements you don't put in $theseOnly
And
array_flip
array_flip() returns an array in flip order, i.e. keys from array become values and values from array become keys.
This just takes the array of names with no keys (it has numeric keys by default), and swaps the key and the value, so
$theseOnly = array_flip(array("postName", "postName2"));
//becomes
$theseOnly = array("postName"=>0, "postName2"=>1);
We need the keys this way so they match what's in the $_GET array. We could always write the array that way, but if your lazy like me then you can just flip it.
session_start();
if(!isset($_SESSION['TestArray'])) $_SESSION['TestArray'] = array();
if(is_array($_GET)){
$_SESSION['TestArray'][] = $_GET;
}
print_r($_SESSION['TestArray']);
Thanks everybody for helping! This worked for me!

Search multi-dimesional array and return specific value

Hard to phrase my question, but here goes. I've got a string like so: "13,4,3|65,1,1|27,3,2". The first value of each sub group (ex. 13,4,3) is an id from a row in a database table, and the other numbers are values I use to do other things.
Thanks to "Always Sunny" on here, I'm able to convert it to a multi-dimensional array using this code:
$data = '13,4,3|65,1,1|27,3,2';
$return_2d_array = array_map (
function ($_) {return explode (',', $_);},
explode ('|', $data)
);
I'm able to return any value using
echo $return_2d_array[1][0];
But what I need to be able to do now is search all the first values of the array and find a specific one and return one of the other value in i'ts group. For example, I need to find "27" as a first value, then output it's 2nd value in a variable (3).
You can loop through the dataset building an array that you can use to search:
$data = '13,4,3|65,1,1|27,3,2';
$data_explode = explode("|",$data); // make array with comma values
foreach($data_explode as $data_set){
$data_set_explode = explode(",",$data_set); // make an array for the comma values
$new_key = $data_set_explode[0]; // assign the key
unset($data_set_explode[0]); // now unset the key so it's not a value..
$remaining_vals = array_values($data_set_explode); // use array_values to reset the keys
$my_data[$new_key] = $remaining_vals; // the array!
}
if(isset($my_data[13])){ // if the array key exists
echo $my_data[13][0];
// echo $my_data[13][1];
// woohoo!
}
Here it is in action: http://sandbox.onlinephpfunctions.com/code/404ba5adfd63c39daae094f0b92e32ea0efbe85d
Run one more foreach loop like this:
$value_to_search = 27;
foreach($return_2d_array as $array){
if($array[0] == $value_to_search){
echo $array[1]; // will give 3
break;
}
}
Here's the live demo.

Remove first element from simple array in loop

This question has been asked a thousand times, but each question I find talks about associative arrays where one can delete (unset) an item by using they key as an identifier. But how do you do this if you have a simple array, and no key-value pairs?
Input code
$bananas = array('big_banana', 'small_banana', 'ripe_banana', 'yellow_banana', 'green_banana', 'brown_banana', 'peeled_banana');
foreach ($bananas as $banana) {
// do stuff
// remove current item
}
In Perl I would work with for and indices instead, but I am not sure that's the (safest?) way to go - even though from what I hear PHP is less strict in these things.
Note that after foreach has run, I expected var_dump($bananas) to return an empty array (or null, but preferably an empty array).
1st method (delete by value comparison):
$bananas = array('big_banana', 'small_banana', 'ripe_banana', 'yellow_banana', 'green_banana', 'brown_banana', 'peeled_banana');
foreach ($bananas as $key=>$banana) {
if($banana=='big_banana')
unset($bananas[$key]);
}
2nd method (delete by key):
$bananas = array('big_banana', 'small_banana', 'ripe_banana', 'yellow_banana', 'green_banana', 'brown_banana', 'peeled_banana');
unset($bananas[0]); //removes the first value
unset($bananas[count($bananas)-1]); //removes the last value
//unset($bananas[n-1]); removes the nth value
Finally if you want to reset the keys after deletion process:
$bananas = array_map('array_values', $bananas);
If you want to empty the array completely:
unset($bananas);
$bananas= array();
it still has the indexes
foreach ($bananas as $key => $banana) {
// do stuff
unset($bananas[$key]);
}
for($i=0; $i<count($bananas); $i++)
{
//doStuff
unset($bananas[$i]);
}
This will delete every element after its use so you will eventually end up with an empty array.
If for some reason you need to reindex after deleting you can use array_values
How about a while loop with array_shift?
while (($item = array_shift($bananas)) !== null)
{
//
}
Your Note: Note that after foreach has run, I expected var_dump($bananas) to return an empty array (or null, but preferably
an empty array).
Simply use unset.
foreach ($bananas as $banana) {
// do stuff
// remove current item
unset($bananas[$key]);
}
print_r($bananas);
Result
Array
(
)
This question is old but I will post my idea using array_slice for new visitors.
while(!empty($bananas)) {
// ... do something with $bananas[0] like
echo $bananas[0].'<br>';
$bananas = array_slice($bananas, 1);
}

Find index of value in associative array in php?

If you have any array $p that you populated in a loop like so:
$p[] = array( "id"=>$id, "Name"=>$name);
What's the fastest way to search for John in the Name key, and if found, return the $p index? Is there a way other than looping through $p?
I have up to 5000 names to find in $p, and $p can also potentially contain 5000 rows. Currently I loop through $p looking for each name, and if found, parse it (and add it to another array), splice the row out of $p, and break 1, ready to start searching for the next of the 5000 names.
I was wondering if there if a faster way to get the index rather than looping through $p eg an isset type way?
Thanks for taking a look guys.
Okay so as I see this problem, you have unique ids, but the names may not be unique.
You could initialize the array as:
array($id=>$name);
And your searches can be like:
array_search($name,$arr);
This will work very well as native method of finding a needle in a haystack will have a better implementation than your own implementation.
e.g.
$id = 2;
$name= 'Sunny';
$arr = array($id=>$name);
echo array_search($name,$arr);
Echoes 2
The major advantage in this method would be code readability.
If you know that you are going to need to perform many of these types of search within the same request then you can create an index array from them. This will loop through the array once per index you need to create.
$piName = array();
foreach ($p as $k=>$v)
{
$piName[$v['Name']] = $k;
}
If you only need to perform one or two searches per page then consider moving the array into an external database, and creating the index there.
$index = 0;
$search_for = 'John';
$result = array_reduce($p, function($r, $v) use (&$index, $search_for) {
if($v['Name'] == $search_for) {
$r[] = $index;
}
++$index;
return $r;
});
$result will contain all the indices of elements in $p where the element with key Name had the value John. (This of course only works for an array that is indexed numerically beginning with 0 and has no “holes” in the index.)
Edit: Possibly even easier to just use array_filter, but that will not return the indices only, but all array element where Name equals John – but indices will be preserved:
$result2 = array_filter($p, function($elem) {
return $elem["Name"] == "John" ? true : false;
});
var_dump($result2);
What suits your needs better, resp. which one is maybe faster, is for you to figure out.

Categories