working with arrays php need some advice - php

need some help figuring this out, ive got some code like so
$q= $conn->query("SELECT * FROM table");
while($array2[] = $q->fetch_object());
array_pop($array2);
if(isset($array2[0]->DATE))
{
$date0 = $array2[0]->DATE;
}else{
$date0 = '';
}
if(isset($array2[1]->DATE))
{
$date1 = $array2[1]->DATE;
}else{
$date1 = '';
}
$data =('DATE1'= $date0,'DATE2'= $date1)
so you can see what the problem is , repeating stuff over and over , its horrible, im sure theres a clean way on doing it, but im not sure how, i tried using a for loop, but if 1 value was not set all other values would get the '' set to them so it didnt work... what i need to end up having is something that increments the 'DATE#' equal to the occurrences inside the $array2
so that if $array2 ranged from $array[0] to $array[4] then inside the $data array i would end up having DATE0 = $date0,DATE1 = $date1,DATE2 = $date2,DATE3 = $date3,DATE4 = $date4,DATE5 = $date5 hopefully that way if for example array2[7] does not exists , it wont throw an error because inside $data it would not exist... hope all that makes sense, i can not find a proper way to describe this.

I don't really get what you are doing with with the while "loop" and the array_pop, but for your other problem, you can use a simple foreach:
foreach ($array2 as $arr)
{
$date[] = (isset($arr->DATE)) ? $arr->DATE : '';
}
This will get you an array with all the dates stored at the corresponding key from 0 to x.

Related

In PHP need all unique combinations of multiple arrays

First, I have looked through dozens of similar questions/answers on this site an have not found any type of solution I could use or modify to use for this problem. There are a lot of things that come into play with this. I got close but it kept running out of memory or other resource so here I am.
I need to create a function that takes a set of arrays and returns all combinations with a specific set of rules. So to start I pull the arrays. There are 9 to start of all various lengths. 4 of the arrays are duplicate set of 4 other individual arrays. Heres how I pull the arrays to start, just so you have an idea of how the data looks.
$prodA1 = Products::where('type','a')->pluck('id')->toArray();
$prodA2 = Products::where('type','a')->pluck('id')->toArray();
$prodB1 = Products::where('type','b')->pluck('id')->toArray();
$prodB2 = Products::where('type','b')->pluck('id')->toArray();
$prodC1 = Products::where('type','c')->pluck('id')->toArray();
$prodC2 = Products::where('type','c')->pluck('id')->toArray();
$prodD1 = Products::where('type','d')->pluck('id')->toArray();
$prodD2 = Products::where('type','d')->pluck('id')->toArray();
$prodE = Products::where('type','e')->pluck('id')->toArray();
I need all set of arrays to be array('prodA1','prodA2','prodB1','prodB2','prodC1','prodC2','prodD1','prodD2','prodE') with the values being IDs bot the name of the array.
Each returned array must be unique
Each individual array can have as many as 96 ids but they all vary
I found the below function which if I add a take(5) to the above so it limits the output seems to produce at least all the combinations which I can then apply other rules to but it takes forever to run. This is the closest I have gotten though, there has to be a faster solution to this. Any help would be appreciated.
public function combinations($arrays, $i = 0) {
if (!isset($arrays[$i])) {
return array();
}
if ($i == count($arrays) - 1) {
return $arrays[$i];
}
// get combinations from subsequent arrays
$tmp = $this->combinations($arrays, $i + 1);
$result = array();
// concat each array from tmp with each element from $arrays[$i]
foreach ($arrays[$i] as $v) {
foreach ($tmp as $t) {
$result[] = is_array($t) ?
array_merge(array($v), $t) :
array($v, $t);
}
}
return $result;
}
EDIT:
The input wound be a set of 9 arrays with ids in them. For instance:
$prodA1 = array(1,2,3,4,5);
$prodA2 = array(1,2,3,4,5);
$prodB1 = array(6,7,8,9);
$prodB2 = array(6,7,8,9);
$prodC1 = array(10,11,12,13);
$prodC2 = array(10,11,12,13);
$prodD1 = array(14,15,16,17);
$prodD2 = array(14,15,16,17);
$prodE = array(18,19,20,21);
returns would look something like
array(1,2,6,7,10,11,14,15,18)
array(1,4,6,8,10,12,14,16,18)
so all the results would be unique, each one would contain 9 values made up of 2 prodA,2 prodB, 2 prodC, 2 prodD and 1 prodE
Hope that clears it up a little.

Searching an array of objects for specific key value pairs

After pulling in some data from a mysql database saving it to a variable, I'm wondering if it's possible to "query" the variable instead of doing another request to the database? I realise I need to search an array of objects based on key and value. So here is an example of what I have.
<?php
[{"customer":1,"item":1,"bought_at":"2016-12-15 11:41:11"},
{"customer":2,"item":1,"bought_at":"2016-12-15 11:43:21"},
{"customer":3,"item":1,"bought_at":"2016-12-16 13:31:11"},
{"customer":1,"item":2,"bought_at":"2016-12-16 12:12:21"},
{"customer":1,"item":3,"bought_at":"2016-12-17 15:13:58"}]
?>
So lets say I need to search it based on the item number and the date (but not time) when the item was bought. The next step would be to return the result as another array of objects. So if I were to search for item 1 bought at 2016-12-15 it would return.
[{"customer":1,"item":1,"bought_at":"2016-12-15 11:41:11"},
{"customer":2,"item":1,"bought_at":"2016-12-15 11:41:21"},]
Is this possible? If so how would I go about doing it?
Regards
EDIT: The reason I originally asked this question was because I had a query inside a nested foreach loop which bothered me. It's a piece of code that builds up a a json table at the back-end to pass information to the front end to draw a google line graph. Also I changed the data slightly in my original question to try to make it easier to read. It's also built in Laravel. The complete code is pretty large so I'm just posting the nested foreach loops. The query is in the second loop and is given the variable $activations.
foreach ($timeRange as $time){
$temp = array();
$timeTwentyFour = date("G", strtotime($time));
$temp[] = array('v' => "Date(01,01,2000,$timeTwentyFour)");
foreach($data as $row){
$count = 0;
$activations = DB::table('customer_display')->where('display_id',$row->id)->where(DB::raw('DATE(created_at)'),$day)->get();
foreach($activations as $activation){
$timestamp = $activation->created_at;
$activationTime = explode(" ", $timestamp)[1];
if (strtotime($activationTime) >= strtotime($time) && strtotime($activationTime) < strtotime($time) + 3600){
$count++;
};
}
$temp[] = array('v' => (float) $count);
//The custom tooltip
$temp[] = array('v' => $time . ' ' . $row->location . '. ' . $count . ($count == 1 ? ' Activation' : ' Activations'));
}
$rows[] = array('c' => $temp);
}
If those are objects in an array and you only wanted the entries where item is 1 you could use array_filter;
$filtered = array_filter($items, function($item){
// only return objects where this is true
return $item->item == 1;
});
If you wanted only items purchased on the 15th use
return date('d', strtotime($item->bought_at)) == 15;
and if you want to see items 1 bought on the 15th you'd use
$filtered = array_filter($items, function($item){
return $item->item === 1
&& date('d', strtotime($item->bought_at)) == 15;
});
Also check out this answer on comparing dates for more information on how to better do that.
Another database request will be the better approach in most cases. A database is optimized for querying data. It can use indexes, etc. Well known databases like MySQL have a query optimalisation. Doing it by hand will be less efficient.
First downloading too much data and then use something like array_filter to linearly search through all the data is far less efficient than just querying the data with the search criteria in the query.
One way to do it is:
//Prepare statement once
$statement = $pdo->prepare("SELECT * FROM table WHERE item = ? AND bought_at = ?");
$statement->execute(array(1, "2016-12-15"));
foreach ($statement->fetchAll() as $array)
//Do something with $array
//reuse prepared statement with another selection criteria
$statement->execute(array(3, "2016-12-16"));
foreach ($statement->fetchAll() as $array)
//Do something with $array

Basic PHP concepts (accessing/declaring array variables)

$result = array();
for ( $i = 10; $i < 101; $i = $i + 10 ){
$result[] = $i;
}
echo implode(", ", $result);
Hello...I'm new to PHP, and this really confused me, declaring a variable array even the code will work without it.
I've found this code here in the forum, regarding the removal of the comma in a for loop. I was wondering what variable is called when it is echoed? Is it the $result = array() or the $result[]? I've tried to remove the $result = array(); and the code still work, is that mean, is it ok to just remove the $result = array();? Does it have some coding issues if it is removed?
The line $result = array(); is used to declare an array.
It's a better approach to use this especially when you have some other previously specified variable $result storing some other value. Mentioning this first line will reset any previously assigned value to $result and declare it as an array datatype.
$result[] = $i; means the value of $i keeps apppending to $result every time.

PHP - Stop need to create hundreds of variables

I'm writing a script and it seems like a bit of a ballache so I came on SO to ask for a little help making my script more dynamic so I create a better version of what I'm doing. I've read into variable variables but I'm still stuck on how I'd use them.
I'll obviously shorten this down but my current script is:
$a0 = $tags['items'][0]['snippet']['tags'];
$a1 = $tags['items'][1]['snippet']['tags'];
$a2 = $tags['items'][2]['snippet']['tags'];
if (!is_array($a0)) { $a0 = array(); }
if (!is_array($a1)) { $a1 = array(); }
if (!is_array($a2)) { $a2 = array(); }
$a0 = array_map('strtolower', $a0);
$a1 = array_map('strtolower', $a1);
$a2 = array_map('strtolower', $a2);
array_count_values(array_merge($a0,$a1,$a2));
I'm looking for a way to dynamically create the variables (For example using an index in a while loop rather than creating these variables uniquely. This obviously is fine on a small scale, but i've currently done 50 of these for each and it's causing serious time problems. Any help is much appreciated
Treat the whole $tags variable as an array and you can do this, similar to the strtolower array_map you have already:
$tagItems = [];
foreach($tags['items'] as $item) {
if (!$item['snippet']['tags'] || !is_array($item['snippet']['tags'])) {
continue;
}
foreach($item['snippet']['tags'] as $tag) {
$tag = strtolower($tag);
if (!isset($tagItems[$tag])) {
$tagItems[$tag] = 0;
}
$tagItems[$tag]++;
}
}
As #FranzGleichmann says, try not to use variable variables, which are a smell and potential security risk, but instead rethink how you want to approach the problem.
You should be able to produce the same output that you get from array_count_values with a nested foreach loop.
foreach ($tags['items'] as $x) { // loop over the list of items
foreach ($x['snippet']['tags'] as $tag) { // loop over the tags from each item
$tag = strtolower($tag);
if (!isset($counts[$tag])) $counts[$tag] = 0;
$counts[$tag]++; // increment the tag count
}
}
No need to create 100 variables. That would cause a headache. Instead, use a simple loop function.
$b = array();
for ($n=1; $n<=100; $n++) {
$a = $tags['items']["$n"]['snippet']['tags'];
if (!is_array($a)) { $a = array(); }
$a = array_map('strtolower', $a);
array_count_values(array_merge($b,$a));
}
I hope it works! Have a nice coding
I would write this in a comment but i will a long one,
Variable Variable, is simply the value of the original var assigned as a var name, which means:
$my_1st_var = 'im_1st';
//use $$
$$my_1st_var = 'im_2nd'; //that is the same of $im_1st='im_2nd';
//results
echo $my_1st_var; // >>> im_1st
echo $im_1st; // >>> im_2nd
that means i created a new var and called it the value of the 1st var which is im_1st and that makes the variable name is $im_1st
also you can set multiple values as a var name:
$var0 = 'a';
$var1 = 'b';
$var2 = 'c';
$var3 = '3';
//we can do this
${$var0.$var1} = 'new var 1'; //same as: $ab = 'new var 1';
${$var1.$var2.$var3} = 'im the newest'; //same as: $bc3 = 'im the newest';
//set a var value + text
${$var0.'4'.$var1} = 'new?'; //same as: $a4b = 'new?';
also $GOLBALS[]; is some kind of $$
hope it helps you understanding what is hard for you about $$ ;)
Alright so dynamically creating variables is easy is a script language like PHP.
You could make $a an array, and instead of $a0, $a1, ... use $a[$i] where $i goes from 0 to 50 or more.
Or you could use this nice funky syntax: ${'a'.$i}. For example:
$i = 0;
${'a'.$i} = 'foobar';
echo $a0; // will output foobar
However you shouldn't do any of this.
What you should do is think about what you are trying to achieve and come up with a different algorithm that doesn't require dynamically named variables.
In this case, something like this looks like it would do the job:
$result = [];
foreach ( $tags['items'] as $item ) {
if ( is_array($item['snippet']['tags']) ) {
$result = array_merge($result, array_map('strtolower',$item));
}
}
array_count_values($result);
This is obviously not tested and from the top of my head, but I hope you get the idea. (EDIT: or check the other answers with similarly rewritten algorithms)

Remove duplicates using array_unique and printing the result

I've been searching and trying for hours, I want to look for duplicates in my variables which print numbers and then eliminate the duplicates leaving just original numbers.
Here is what I've been trying:
$priceminpps = get_field('price_minpps');
$pricemaxpps = get_field('price_maxpps');
$priceminunit = get_field('price_minunit');
$pricemaxunit = get_field('price_maxunit');
$find_duplicates = array($priceminpps, $pricemaxpps, $priceminunit, $pricemaxunit, );
$result = array_unique($find_duplicates);
print($result);
But it doesn't work, can anyone help?
Double check if array_unique doesn't do what it should.
If it's realy array_unqiue() i would generate a new array and push the unique numbers in this new one. You can check if it's already in the new array with in_array(number-to-check, $array).
If in_array() doesn't return true, add it to the unique-number-array.
Example:
$result = array();
foreach ($find_duplicates as $number) {
if(!in_array($number, $result)) {
$result[] = $number;
}
}

Categories