I am having an issue removing duplicates from the result of a foreach loop.
The problem more so is the process of how i have the data.
Here is grab the data i need.
$results = mysql_query($query);
while($rows = mysql_fetch_assoc($results)){
extract($rows);
I am trying to grab a column of item_specifiations. Within this column there are multiple data, separated by commas. Some items have more data that others, some are lacking certain data.
$specs = explode("," , $item_specification);
I separate the data using the above method.Then i run the loop to show the data for each item in the DB.
foreach($specs as $spec => $key ){
This now returns every data separated for each item (UPC, PRODUCT_NAME, ETC), which is exactly what i need. But i need only the "BRAND" of the item. So i do the following.
if (strpos($key, 'Brand') === 0) {
$brand = explode(':', $key);
}
Now the problem i am having is certain items having duplicate brand names.
So i want to remove any strings that are returning. The problem is, since this is a loop, there is no way to compare the strings with each other. Each is its own array, so i am dealing with multiple multi-dimensional arrays. I cant figure a way to push them into 1 array then compare, or using something like unique_array.
Any suggestions or help would be appreciated. I have been stuck for awhile.
Use array_unique:
$var = [];
foreach($specs as $spec => $key) {
if(strpos($key,'Brand') === true ) {
$brand[]= implode(',', array_unique(explode(', ',$key)));
}
}
print_r($brand);
Related
When populating a dropdown list using a foreach statement on array, it display a single item as a string. however, it can populate the list correctly using this syntax ["test1","test2"]
foreach($dataNew[$i]['message'] as $x => $item){
$myMessage[]='"'.$item['Lots'].'"';
}
$lots=[implode (',', $myMessage)];//does not work
//$lots=['4342355555555#1', '32335455#5'];//works fine
$dataNew[$i]=['Lots'=>[$lots]];
Any ideas?
Here is an example of corrext concatination, assuming some details of your problem, which are not quite clear by now.
Assuming: the $dataNew parameter holds an array of strings at [$i]['message'] which contains lots, which are seperated by commas, and come from some statistical process.
The output shall be an two-dimensional array, which merges all lots of one iteration into one list. So the reslut is a list of lists of lots (foreach $i).
$currentLotsList = $dataNew[$i]['message'];
//iterating over the lots of the current sample - which are a chain of strings seperated by commas
foreach($currentLotsList as $csvLots){
//getting the lots into an array
$currentLotsArray = explode(",", $csvLots);
//adding this list to the major list of $i,
if(!isset($dataNew[$i]['Lots']) ){
//createing the array if not set now.
$dataNew[$i]['Lots'] = [];
}
$dataNew[$i]['Lots'] = array_merge($dataNew[$i]['Lots'], $currentLotsArray);
}
I have three lists of keys and values separated by comma, resulted from a query in DB using group_concat, as follows:
JSON encoded hardware info:
{
"2":"400",
"4":"1500Mhz",
"3":"GDDR5",
"5":"12"
}
specifications keys:
1,2,3,4,5
specifications values:
Lithography,# of Cores,# of Threads,Base Frequency,Cache
Here's how I did combine them:
$dbSpecs = array_combine(explode(',',$hwKeys),explode(',',$hwValues));
$hwspec = json_decode($info, true);
$combined = [];
foreach ($dbSpecs as $k => $v) {
if(array_key_exists($k, $hwspec)){
$combined[$v] = $hwspec[$k];
}
}
I think keys and values can be stringified instead of using two columns in DB, but this is another story.
Is there a way to improve this piece of PHP?
I have this object containing one row and many keys/variables with numbered names.
I need to pass each of them one at a time to another function. How do I loop through the keys instead of the rows?
The code would look like this:
foreach ($object['id'] as $row):
$i++;
$data['myInfo'][$i] = $this->get_data->getInfo('data1', 'id', $row->{'info'.$i.'_id'});`
but this obviously won't work since it's looping through the rows/instances of an object, and I have only one row in my $object['id'] object (with info1_id, info2_id, info3_id, info4_id... etc keys), so the loop stops after just one cycle. And I really don't feel like typing all of that extra code by hand, there's gotta be solution for this. :)
You can just iterate through your object like an array :
foreach ($object['id'] as $row) {
foreach ($row as $k => $v) {
$id = substr($k, 4, strpos($k, '_')-4);
$data['myInfo'][$id] = $this->get_data->getInfo('data1', 'id', $v);`
}
}
Thanks for the directions Alfwed, I didn't know you could use foreach loop for anything other than instances of an object or arrays (only started learning php a week or so ago), but now it looks pretty straight forward. that's how I did it:
foreach ($object['id'] as $row):
foreach ($row as $k=>$v):
$i++;
if ($k == print_r ('info'.$i.'_id',true)){
$data['myinfo'][$i] = $this->get_db->getRow('products', 'id','info'.$i.'_id');
<...>
in my case, I knew how many and where were those values, so I didn't have to worry about index values too much.
I'm trying to dynamically generate html select options using PHP based on whatever its stored in mysql database.
the column that stores the data called sizez.
the data in that column is stored like so:
small,large,xlarge,xxlarge
so basically the data is separated by a comma.
now in my php page I simply pull the data and display it on my page using a while loop for each product that is stored in the mysql database.
the issue that I am having is that I need to generate a select option dropdown list based on the sizez column for each item.
for that I am using the explode() function and it will generate the select option successfully too.
however, the issue is that it will only get the strings from the first sizez column and ignores the rest of the items But it will display the string from the first column for other items too and it repeats them!
this is my code:
while($row = mysqli_fetch_array($query, MYSQLI_ASSOC)){
$id = $row["id"];
$sizez = $row["sizez"];
$sizez = preg_replace('/\.$/', '', $sizez); //Remove dot at end if exists
$array = explode(',', $sizez); //split string into array seperated by ','
foreach($array as $value) //loop over values
{
//echo $value . PHP_EOL; //print value
$sizesOption .='<option>'.$value.'</option>';
}
$all_list .="<select>
'.$sizesOption.'
</select>";
so I thought to put the foreach($array as $value) inside the $all_list .= but that approach is wrong.
could someone please advise on this issue?
any help would be appreciated.
EDIT:
The expected result should be like this:
item one item two item three
small large small
large xxlarge xxlarge
However, with my code I get the result like this:
item one item two item three
small small small
large large large
small small
large large
small
large
so basically, it will get the sizes column from the first item and it will repeat it inside select options for other items exactly like the example above.
Since you are generating separate <select> for each iteration, you have to reset $sizeOptions. I suggest using arrays instead of just concatenating strings:
$allList = array();
while($row = mysqli_fetch_array($query, MYSQLI_ASSOC)){
$sizesOption = array();
$sizez = preg_replace('/\.$/', '', $row["sizez"]);
$array = explode(',', $sizez);
foreach ($array as $value) {
$sizesOption[] = "<option>{$value}</option>";
}
$all_list[] = '<select>'.implode("\r\n", $sizesOption).'</select>';
}
echo implode("\r\n", $allList);
From what you have posted it looks like you're regenerating $all_list in every iteration of your while loop.
So if you echo $all_list outside of the while loop it will only have the last iteration available - all the other ones having been overwritten during the process of the while loop.
Maybe I am wrong. but as simple as:
$all_list ="<select>".$sizesOption."</select>";
Close the opening braces for while loop before the '$all_list .="' statement.You are iterating the statement inside while loop.
`
while($row = mysqli_fetch_array($query, MYSQLI_ASSOC))
{
$id = $row["id"];
$sizez = $row["sizez"];
$sizez = preg_replace('/\.$/', '', $sizez); //Remove dot at end if exists
$array = explode(',', $sizez); //split string into array seperated by ','
foreach($array as $value) //loop over values
{
//echo $value . PHP_EOL; //print value
$sizesOption .='<option>'.$value.'</option>';
}
}
$all_list .="<select>
'.$sizesOption.'
</select>";
`
May be this will work
I figured it out. Thanks to Justinas's answer. I realized that I had to put my php variable inside the while loop.
so all I had to do was to put $sizesOption =array(); inside my while loop and everything works fine now.
P.S. i haven't made any other changes to my code above.
I have the following array:
$masterlist=[$companies][$fieldsofcompany][0][$number]
The third dimension only exists if the field selected from $fieldsofcompany = position 2 which contains the numbers array. Other positions contain regular variables. The 3rd dimension is always 0 (the numbers array) or Null. Position 4 contains numbers.
I want to cycle through all companies and remove from the $masterlist all companies which contain duplicate numbers.
My current implementation is this code:
for($i=0;$i<count($masterlist);$i++)
{
if($masterlist[$i][2][0][0] != null)
$id = $masterlist[$i][0];
for($j=0;$j<count($masterlist[$i][2][0]);$j++)
{
$number = $masterlist[$i][2][0][$j];
$query = "INSERT INTO numbers VALUES('$id','$number')";
mysql_query($query);
}
}
Which inserts numbers and associated IDs into a table. I then select unique numbers like so:
SELECT ID,number
FROM numbers
GROUP BY number
HAVING (COUNT(number)=1)
This strikes me as incredibly brain-dead. My question is what is the best way to do this? I'm not looking for code per se, but approaches to the problem. For those of you who have read this far, thank you.
For starters, you should prune the data before sticking it into the database.
Keep a look up table that keeps track of the 'number'.
If the number is not in the look up table then use it and mark it, otherwise if its in the look up table you can ignore it.
Using an array for the look up table and with keys being the 'number' you can use the isset function to test if the number has appeared before or not.
Example pseudo code:
if(!isset($lookupTable[$number])){
$lookupTable[$number]=1;
//...Insert into database...
}
Now that I think I understand what you really want, you might want to stick with your two-pass approach but skip the MySQL detour.
In the first pass, gather numbers and duplicate companies:
$duplicate_companies = array();
$number_map = array();
foreach ($masterlist as $index => $company)
{
if ($company[2][0][0] === null)
continue;
foreach ($company[2][0] as $number)
{
if (!isset($number_map[$number])
{
// We have not seen this number before, associate it
// with the first company index.
$number_map[$number] = $index;
}
else
{
// Both the current company and the one with the index stored
// in $number_map[$number] are duplicates.
$duplicate_companies[] = $index;
$duplicate_companies[] = $number_map[$number];
}
}
}
In the second pass, remove the duplicates we have found from the master list:
foreach (array_unique($duplicate_companies) as $index)
{
unset($masterlist[$index]);
}