I’m new to PHP so this might be a very long questions. First of all I can’t normalise the database the way it has been designed it has to be kept like this. I’ll explain the scenario first: I have locations on a map, those locations can have as many products attached to them as possible. My issue is that I want to concatenate two values together in an array to make them into a string so I can store it in the db and then use it.
I’m having issues with a particular record, this record 1234 is causing me issues. As it has two Ratings attached to it but I need to concatenate them and put them into another array so I can store in my database in a particular field as strings instead of separate ints.
Below is the code, as you’ll see I did a if statement inside the code I want to use to debug what is happening in that particular record.
$ratingString = array();
$rating = 0;
foreach( //not sure if this foreach is related to the question)
if(true == isset($ratingString[$location[‘id’]])){
echo ‘in set’;
$ratingString[$location[‘id’]][‘ratingString’] = strval( $ratingString[$location[‘id’]][‘ratingString’]).’,’.$rating;
}else {
if($location[‘id’] == 1234){
echo ‘not in set’
$ratingString[$location[‘id’]][‘ratingString’] = $rating;
Print_r($ratingString);
} }
When I debug this, it shows me two variables in rating string.
Not in set
string() “ratingString”
array(1){
[1234] =>
array(1) {
[“ratingString”] =>
int(2)
}
}
Not in set
string() “ratingString”
array(1){
[1234] =>
array(1) {
[“ratingString”] =>
int(3)
}
}
So what I need help with, is how could I concatenate the two so that it would be [ratingString] => string 2,3 and how would I change my code so that it would work for all my locations and not just this particular record.
I'm trying to add 4 arrays into one array ($all_prices) and then check the values of each key in each individual array against $all_prices to make sure that they are unique. If they are not I want to add a 0 to the end of if to make it unique (so 0.50 becomes 0.500).
For some reason I'm getting the following error, despite the fact that I already changed the data type from decimal to varchar:
array_count_values(): Can only count STRING and INTEGER values!
Edit
Here is a snippet from dd($all_prices)
array(4) { [0]=> array(9) { ["14.45"]=> string(8) "sample 1" ["12.40"]=>
string(8) "sample 2" ["14.13"]=> string(8) "sample 3" ["15.11"]=>
string(8) "sample 4"
Code:
$all_prices = [$list_a_prices, $list_b_prices, $list_c_prices, $list_d_prices];
$price_count = array_count_values($all_prices);
foreach($list_b_prices as $key => $value){
if($price_count[$key] >= 2){
$key . "0";
}
}
Where am I going wrong? Is there is a way to leave the data type as Decimal?
I think you should not index by the prices, after all from a math point of view 5.0 and 5.00 does not make difference at all.
If you are obtaining values from a database you will get strigs everywhere. So you will have to cast (int)$key for the keys.
And in your foreach you are changing a temporary variable. $key exists only for the current iteration of the loop you will want to declare it as:
foreach($list_b_prices as &(int)$key => $value){
if($price_count[$key] >= 2){
$key . "0";
}
}
Note the ampersand and the casting to integer. Although i'm not sure which will come first. But again: I think indexing by some different value shall give you a better result.
What about a nested loop ?
$all_prices = [$list_a_prices, $list_c_prices, $list_d_prices];
foreach($list_b_prices as $key => $value){
foreach($all_prices as $array){
if(isset($array[$key])){
$list_b_prices[$key] .= '0';
}
}
}
Not elegant but it does the trick.
I am trying to add an array to an existing array. I am able to add the array using the array_push . The only problem is that when trying to add array that contains an array keys, it adds an extra array within the existing array.
It might be best if I show to you
foreach ($fields as $f)
{
if ($f == 'Thumbnail')
{
$thumnail = array('Thumbnail' => Assets::getProductThumbnail($row['id'] );
array_push($newrow, $thumnail);
}
else
{
$newrow[$f] = $row[$f];
}
}
The fields array above is part of an array that has been dynamically fed from an SQl query it is then fed into a new array called $newrow. However, to this $newrow array, I need to add the thumbnail array fields .
Below is the output ( using var_dump) from the above code. The only problem with the code is that I don't want to create a seperate array within the arrays. I just need it to be added to the array.
array(4) { ["Product ID"]=> string(7) "1007520"
["SKU"]=> string(5) "G1505"
["Name"]=> string(22) "150mm Oval Scale Ruler"
array(1) { ["Thumbnail"]=> string(77) "thumbnails/products/5036228.jpg" } }
I would really appreciate any advice.
All you really want is:
$newrow['Thumbnail'] = Assets::getProductThumbnail($row['id']);
You can use array_merge function
$newrow = array_merge($newrow, $thumnail);
Alternatively, you can also assign it directly to $newrow:
if ($f == 'Thumbnail')
$newrow[$f] = Assets::getProductThumbnail($row['id']);
else
...
Or if you want your code to be shorter:
foreach($fields as $f)
$newrow[$f] = ($f == 'Thumbnail')? Assets::getProductThumbnail($row['id']) : $row[$f];
But if you're getting paid by number of lines in your code, don't do this, stay on your code :) j/k
I have an array, let us say, $breadcrumb = array("home" , "groups", "Create content", "some other element" "so on"); I want to check if it contains a string "Create content" and then unset the string, but my problem is that "Create content" is a link (anchored) and not just a plain string, I tried in_array(), but not successful. How do I look for it, to make it more clear?
Here is my code:
<?php
function phptemplate_breadcrumb($breadcrumb) {
if (!empty($breadcrumb)) {
if(in_array("Create content",$breadcrumb)){
foreach($breadcrumb as $key => $value){
if("Create content" == strip_tags($value)){
unset($breadcrumb[$key]);
}
}
}
}
return '<div class="breadcrumb">'. implode(' › ', $breadcrumb) .'</div>';
}
Note: I know it can be done anyway if I ommit in_array() check but I don't want to loop through the array unecessarily, if the 'Create content' is not in the array.
Edit: actual array is:
array(
[0]=>home
[1]=> groups
[2]=> my group
[3]=> Create content
)
here 'Create content' may occupy any position.
Note: all elements are links (anchored).
If your real array is something like
array(
[0]=> home
[1]=> groups
[2]=> my group
[3]=> Create content
)
then you can try to use preg-grep so as to return all items that match your regExp pattern:
$content_links = preg_grep("/[YOUR REGEXP HERE]/", $breadcrumb);
// if you have matching items
if (0 < sizeof($content_links)) {
// do some stuff - do `foreach` loop or use `array_diff`
}
UPD:
Or even you can use PREG_GREP_INVERT as third parameter and get all items that doens't match RegExp pattern.
I'm used to perl's map() function where the callback can assign both the key and the value, thus creating an associative array where the input was a flat array. I'm aware of array_fill_keys() which can be useful if all you want to do is create a dictionary-style hash, but what if you don't necessarily want all values to be the same? Obviously all things can be done with foreach iteration, but what other (possibly more elegant) methods exist?
Edit: adding an example to clarify the transformation. Please don't get hung up on the transformation, the question is about transforming a flat list to a hash where we can't assume that all the values will be the same.
$original_array: ('a', 'b', 'c', 'd')
$new_hash: ('a'=>'yes', 'b'=>'no', 'c'=>'yes', 'd'=>'no')
*note: the values in this example are arbitrary, governed by some business logic that is not really relevant to this question. For example, perhaps it's based on the even-oddness of the ordinal value of the key
Real-world Example
So, using an answer that was provided here, here is how you could parse through the $_POST to get a list of only those input fields that match a given criteria. This could be useful, for example, if you have a lot of input fields in your form, but a certain group of them must be processed together.
In this case I have a number of input fields that represent mappings to a database. Each of the input fields looks like this:
<input name="field-user_email" value="2" /> where each of this type of field is prefixed with "field-".
what we want to do is, first, get a list of only those input fields who actually start with "field-", then we want to create an associative array called $mapped_fields that has the extracted field name as the key and the actual input field's value as the value.
$mapped_fields = array_reduce( preg_grep( '/field-.+/', array_keys( $_POST ) ), function( $hash, $field ){ $hash[substr( $field, 6 )] = $_POST[$field]; return $hash; } );
Which outputs:
Array ( [date_of_birth] => 1 [user_email] => 2 [last_name] => 3 [first_name] => 4 [current_position] => 6 )
(So, just to forestall the naysayers, let me agree that this bit of compact code is arguably a lot less readable that a simple loop that iterates through $_POST and, for each key, checks to see if it has the prefix, and if so, pops it and its value onto an array)
I had the exact same problem some days ago. It is not possible using array_map, but array_reduce does the trick.
$arr = array('a','b','c','d');
$assoc_arr = array_reduce($arr, function ($result, $item) {
$result[$item] = (($item == 'a') || ($item == 'c')) ? 'yes' : 'no';
return $result;
}, array());
var_dump($assoc_arr);
result:
array(4) { ["a"]=> string(3) "yes" ["b"]=> string(2) "no" ["c"]=> string(3) "yes" ["d"]=> string(2) "no" }
As far as I know, it is completely impossible in one expression, so you may as well use a foreach loop, à la
$new_hash = array();
foreach($original_array as $item) {
$new_hash[$item] = 'something';
}
If you need it in one expression, go ahead and make a function:
function array_map_keys($callback, $array) {
$result = array();
foreach($array as $item) {
$r = $callback($item);
$result[$r[0]] = $r[1];
}
return $result;
}
This is a clarification on my comment in the accepted method. Hopefully easier to read. This is from a WordPress class, thus the $wpdb reference to write data:
class SLPlus_Locations {
private $dbFields = array('name','address','city');
public function MakePersistent() {
global $wpdb;
$dataArray = array_reduce($this->dbFields,array($this,'mapPropertyToField'));
$wpdb->insert('wp_store_locator',$dataArray);
}
private function mapPropertyToField($result,$property) {
$result[$property] = $this->$property;
return $result;
}
}
Obviously there is a bit more to the complete solution, but the parts relevant to array_reduce() are present. Easier to read and more elegant than a foreach or forcing the issue through array_map() plus a custom insert statement.
Nice!
A good use case of yield operator!
$arr = array('a','b','c','d');
$fct = function(array $items) {
foreach($items as $letter)
{
yield sprintf("key-%s",
$letter
) => "yes";
}
};
$newArr = iterator_to_array($fct($arr));
which gives:
array(4) {
'key-a' =>
string(3) "yes"
'key-b' =>
string(3) "yes"
'key-c' =>
string(3) "yes"
'key-d' =>
string(3) "yes"
}