Change array keys to specific strings - php

I am looking for a way to explicitly change some array keys as they will always be the same and the array length will always be the same and then output a single key based on the lowest value. Here is where I am at:
The array code itself look like this:
$t = array($low_score_1,$low_score_2,$low_score_3,$low_score_4,$low_score_5,$low_score_6,$low_score_7,$low_score_8);
Output example:
array(8) { [0]=> string(2) "11" [1]=> string(2) "15" [2]=> string(2) "13" [3]=> string(2) "12" [4]=> string(2) "18" [5]=> string(2) "16" [6]=> string(2) "16" [7]=> string(2) "14" }
So I want to change all 8 keys to each be a specific string. So I need to change the keys and then only output the key of the lowest value in the array. I can only at the moment output the value of the lowest in the array like so:
echo min($t);
And from the array above you can see that 11 is the lowest so that is the one I want to show BUT by ke and not value...
UPDATE
I have managed to set my keys and output both the keys with their retrospective pairs but I just want to show the lowest value by its key.
$t = array(
'a' => $low_score_1,
'b' => $low_score_2,
'c' => $low_score_3,
'd' => $low_score_4,
'e' => $low_score_5,
'f' => $low_score_6,
'g' => $low_score_7,
'h' => $low_score_8,
);
reset($t);
while (list($key, $val) = each($t)) {
echo "$key => $val\n";
}
The output of this looks like:
a => 11 b => 15 c => 13 d => 12 e => 18 f => 16 g => 16 h => 14

As mentioned it's a simple 'find minimum' problem.
Only that you want to save the key of the minimum value.
$t = array($low_score_1,$low_score_2,$low_score_3,$low_score_4,$low_score_5,$low_score_6,$low_score_7,$low_score_8);
//Setting new keys
$t2 = array();
foreach($t as $key => $val){
$key2 = 'score_' . ($key+1);
$t2[$key2] = $val;
}
//Finding the minimum
$min = $t2['score_1'];
$min_key = 0;
foreach($t2 as $key => $val){
if($val < $min){
$min = $val;
$min_key = $key;
}
}
//output
print_r($t2);
echo $min; // the min value
echo $min_key; // the key of the min value

Related

how to split a string and build an associative array php?

How to split a string in PHP ? For example, if i have the string like
Array([0] => "1=>10,2=>9,3=>7,1=>9,2=>8,3=>7");
how can i get
Array([0] => 1=>10,2=>9,3=>7 [1] => 1=>9,2=>8,3=>7);
and later i want to build an associative array like for example,
$ratings = array(6533 => ['Build Quality' => [1=>10,2=>9,3=>7],
'Versatility' => [1=>9,2=>8,3=>7],
'value' => [1=>9.5,2=>7,3=>6]]);
//takes the current post id and returns an product ratings array
function get_ratings($current_post_id){
$product_post = get_post($current_post_id);
preg_match_all("/\[v360_product_table\s.*?\]/", $product_post>post_content, $product_elements);
$product_elements = $product_elements[0][0];
preg_match_all('/"([^"]+)"/', $product_elements, $parameters);
$product_params = $parameters[0][0];
$rating_params = preg_split('","', $product_params);
$rating_factors = str_replace('"', '', $rating_params);
$b = print_r($rating_factors);
/* output: Array ( [0] => Build Quality [1] => Versatality [2] => Adoptability) */
$product_rank = $parameters[0][1];
/* output: Array ( [0] => 1=>10,2=>9,3=>7,1=>9,2=>8,3=>7 ) */
$rank_split = preg_split('"**have to split it here**"', $product_rank);
$rank_values = str_replace('"', '', $rank_split);
$assoc_array = array_combine($rating_factors, $rank_values);
/* needs to construct an array like '$ratings' */
$ratings = array(6533 => ['Build Quality' => [1 => 10, 2 => 8, 3 => 7],
'Versatility' => [1 => 9, 2 => 9, 3 => 8], 'Value' => [1 => 10, 2 => 8,3 => 8]]);
return $ratings[$current_post_id];
}
From your examples, I'm guessing you want to split the string by commas followed by the number 1. To do this, you can use preg_split() with a positive lookahead:
$string = "1=>10,2=>9,3=>7,1=>9,2=>8,3=>7";
$split = preg_split('/,(?=1\b)/', $string);
var_dump($split);
Gives:
array(2) {
[0]=>
string(15) "1=>10,2=>9,3=>7"
[1]=>
string(14) "1=>9,2=>8,3=>7"
}
This function will parse out the whole string into a nested array:
function split_string($string)
{
$split = array();
foreach (preg_split('/,(?=1\b)/', $string) as $row => $part1) {
foreach (explode(',', $part1) as $part2) {
list($key, $value) = explode('=>', $part2, 2);
$split[$row][$key] = $value;
}
}
return $split;
}
Tested as follows (in php 5.6):
$string = "1=>10,2=>9,3=>7,1=>9,2=>8,3=>7";
$split = split_string($string);
var_dump($split);
Gives this output:
array(2) {
[0]=>
array(3) {
[1]=>
string(2) "10"
[2]=>
string(1) "9"
[3]=>
string(1) "7"
}
[1]=>
array(3) {
[1]=>
string(1) "9"
[2]=>
string(1) "8"
[3]=>
string(1) "7"
}
}
You could then use array_combine() for example to merge in the names:
$string = "1=>10,2=>9,3=>7,1=>9,2=>8,3=>7";
$split = split_string($string);
var_dump(array_combine(array('Build Quality', 'Versatility'), $split));

Slicing two values from array and adding to new array in for loop

I am having issues with a php loop.
Perhaps there is a better way to do this. Currently my post is returning
array(4) {
[1]=> string(2) "on"
["1-qty"]=> string(1) "1"
[5]=> string(2) "on"
["5-qty"]=> string(1) "9"
}
I am trying to make a new array of 2 arrays such as the following
array(2) {
array(2) {
[category]=> string(2) "1"
["qty"]=> string(1) "1"
}
array(2) {
[category]=> string(2) "5"
["qty"]=> string(1) "9"
}
}
I have tried about every foreach and for loop that I can manage to put together. The main problem being the first value I need is the key not the value of the first array. Then I need to take the first two arrays from the main array and add to a new array with the first array key being the new value of the first key category in the array, and the value of the second array being the value of the new key qty in the array, and repeat by groups of 2 foreach set that is in the post variable
Current loop (not working)
$data = $this -> input -> post();
$dCount = count($data);
$newCount = $dCount / 2;
$fin = array();
for ($i = 0; $i <= $newCount; $i++) {
$vals = array_slice($data, 0, $i + 1, true);
$qty = array_slice($vals, 0, $i , true);
$key = current(array_keys($qty));
$final = array('category' => $key, 'qty' => $qty[$key . '-qty']);
$fin[] = $final;
}
Try this way:
$source_arr = array(1 => "on", "1-qty" => 1, 5 => "on", "5-qty" => "9");
$result_arr = array();
foreach ($source_arr as $key => $value) {
if ($value == "on" && isset($source_arr[$key . "-qty"])) {
$result_arr[] = array(
'category' => $key,
'qty' => $source_arr[$key . "-qty"]
);
}
}

Php array get all values that are repeating

I have a Php array that have values of times as array values and timestamps as key array is like this:
array(
144454884=>"12:00am", 145454884=>"12:30am", 144474884=>"1:00am", 144454864=>"1:30am", 143354884=>"1:00am", 144654884=>"1:30am", 1444567584=>"2:00am "
);
Timestamp values in above example are not real I wrote an example they are useless anyway unless your timezone matches mine.
Problem:
I need to get "1:00am" and "1:30am" twice I can get repeating values 1 time as shown in answer here:
php return only duplicated entries from an array
I need both repeating values two times with both keys and values being repeated because I need to eliminate those timestamps from week time on my system because of daylight saving a time is repeating and I don't want to show 1:00am at all I just want to show this time as unavailable.
I am not 100% sure what you wanted but this is what I think you need.
Assuming your input array is called $a
$b = array_flip(array_flip($a));
$c = array_diff_key($a, $b);
$b will contain an array of unique values.
$c will contain the elements that were removed.
Results of $b and $c are as follows:
array(5) {
[144454884] = string(7) "12:00am"
[145454884] = string(7) "12:30am"
[143354884] = string(6) "1:00am"
[144654884] = string(6) "1:30am"
[1444567584] = string(7) "2:00am "
}
array(2) {
[144474884] = string(6) "1:00am"
[144454864] = string(6) "1:30am"
}
This code works :
<?php
$array_new = [];
$array_tmp = [];
$array = array(1=>'1233',2=>'12334',3 =>'Hello' ,4=>'hello', 5=>'U');
//loop trough all elements in array and for ever element create key
//For "world" key is "world"
//For "World" key is "world"
//For "WORLD" key is "world"
//So all this cases have same key and differenet representation eg. "world" => ["world","World","WORLD"]
foreach($array as $k => $v){
$index = strtolower($v);
$array_tmp[$index][] = $v;
}
//loop trough new array with new keys and if there are more than one element(> 1) for some key, all of his representations put in new array
foreach($array_tmp as $k => $v){
if(count($v) > 1){
foreach($v as $k2 => $v2){
$array_new[] = $v2;
}
}
}
echo '<pre>';
print_r($array_new);
echo '<pre>';
A possible solution keeping the key information (I will assign the intermediate results to their own variables otherwise it can be confusing to read)
$array = array(
143354883 => "1:00am",
144454884 => "12:00am",
145454884 => "12:30am",
144474884 => "1:00am",
144454864 => "1:30am",
143354884 => "1:00am",
144654884 => "1:30am",
1444567584 => "2:00am ",
0 => 4,
1 => 4,
2 => 4,
3 => "Test",
4 => "TEST",
5 => "test "
);
// Used this array_iunique function: http://stackoverflow.com/questions/2276349/case-insensitive-array-unique
function array_iunique($array) {
return array_intersect_key(
$array,
array_unique(array_map("StrToLower",$array))
);
}
$unique = array_iunique($array);
// Then get the difference by key, that will give you all the duplicate values:
$diff_key = array_diff_key($array, $unique);
// Now we have to find the values that are in the $diff_key and the $unique because we also want to have those:
$correspondingValues = array_uintersect($unique, $diff_key, "strcasecmp");
// Then we have to combine the $duplicate values with the $diff_key and preserve the keys:
$result = array_replace($correspondingValues, $diff_key);
var_dump($result);
Will result in:
array(10) {
[143354883]=>
string(6) "1:00am"
[144454864]=>
string(6) "1:30am"
[0]=>
int(4)
[3]=>
string(4) "Test"
[144474884]=>
string(6) "1:00am"
[143354884]=>
string(6) "1:00am"
[144654884]=>
string(6) "1:30am"
[1]=>
int(4)
[2]=>
int(4)
[4]=>
string(4) "TEST"
}

PHP, How to find next greater key value from array

I have an array like this:
$pricing = array(
"2" => 8.23,
"5" => 10.97,
"10" => 13.28,
"15" => 15.40,
"20" => 18.15,
"25" => 20.36,
"30" => 22.84,
"40" => 25.60,
"50" => 28.35,
"60" => 31.89,
"70" => 36.23,
"80" => 39.40,
"90" => 42.52,
"100" => 44.75
);
And I have a variable that has the client given value from 1 to 100.
Question is: what is the best and fastest way to find the next biggest key, if the key itself doesn't exist?
E.g. I have a variable with value of 12, and I need to get the price for that. According to the array here, the price would be 15.40 because the next biggest key is 15.
I could try and find key number '12', and if it doesn't exist, i would add one(12+1) and try again, until next key is found, but is there any function that could do this for me, or something even better/faster?
Edit: Clarification about the structure of the array.
Array is like it is in the example here. Keys are ordered as can be seen.
A simple foreach will do, but to guard against either empty arrays or a needle that's higher than the highest key, here's an implementation that will cover that as well:
function find(array $pricing, $needle)
{
$last = null; // return value if $pricing array is empty
foreach ($pricing as $key => $value) {
if ($key >= $needle) {
return $key; // found it, return quickly
}
$last = $key; // keep the last key thus far
}
return $last;
}
$result = find($pricing, 12); // 15
$result = find($pricing, 101); // 100
$result = find([], 12); // null
Assuming you are looking for the 'requiredKey' and that the array is sorted by key
This seem to do what you want.
Code:
<?php
$pricing = array(
"2" => 8.23,
"5" => 10.97,
"10" => 13.28,
"15" => 15.40,
"20" => 18.15,
"25" => 20.36,
"30" => 22.84,
"40" => 25.60,
"50" => 28.35,
"60" => 31.89,
"70" => 36.23,
"80" => 39.40,
"90" => 42.52,
"100" => 44.75
);
// What key we want...
$requiredKey = 12;
// outout in here
$foundKey = -1;
$foundValue = -1;
// always run the loop once...
do {
$foundKey = key($pricing); // store the current details
$foundValue = current($pricing);
next($pricing); // will be equal or greater
}
while ( current($pricing) !== false
&& $foundKey < $requiredKey);
echo '<pre>';
echo '<br />', 'key: ', $foundKey, ' value: ', $foundValue;
echo '</pre>';
Output:
key: 15 value: 15.4
Your logic is ok, you can do it using next()
http://php.net/manual/en/function.next.php
$search = 12;
$pricing = array(
"2" => 8.23,
"5" => 10.97,
"10" => 13.28,
"15" => 15.40,
"20" => 18.15,
"25" => 20.36,
"30" => 22.84,
"40" => 25.60,
"50" => 28.35,
"60" => 31.89,
"70" => 36.23,
"80" => 39.40,
"90" => 42.52,
"100" => 44.75
);
$result = null;
if (!isset($pricing[$search])) {
do {
} while (next($pricing) && $search > key($pricing));
$result = current($pricing);
} else {
$result = $pricing[$search];
}
echo $result;
Your lookup array will not change so it makes perfect sense to declare it as a constant (instead of a variable) and to make your code immediately understandable, give the constant a self-explanatory name.
const THRESHOLD_PRICES = [
2 => 8.23,
5 => 10.97,
10 => 13.28,
15 => 15.40,
20 => 18.15,
25 => 20.36,
30 => 22.84,
40 => 25.60,
50 => 28.35,
60 => 31.89,
70 => 36.23,
80 => 39.40,
90 => 42.52,
100 => 44.75
];
A valuable benefit of using a constant is that it is not necessary to explicitly pass the data into a function's scope.
In your function, I recommend type hinting the parameter and the return value -- again to make the code easier to understand.
Before iterating the array, do a quick scan of the keys for an exact match. Because of the way that php treats arrays as hashmaps, this is a very low-cost technique.
Next iterate the array and break the loop as soon as the array key is larger than the search value.
Regardless of if/when the loop breaks, the final iteration will declare the targeted price, so unconditionally return that float value.
function getThresholdPrice(int $search): float {
if (isset(THRESHOLD_PRICES[$search])) {
return THRESHOLD_PRICES[$search];
}
foreach (THRESHOLD_PRICES as $threshold => $price) {
if ($threshold > $search) {
break;
}
}
return $price;
}
Tests: (Demo)
foreach (range(1, 105, 13) as $test) {
printf("%d => %.02f\n", $test, getThresholdPrice($test));
}
Output:
1 => 8.23
14 => 15.40
27 => 22.84
40 => 25.60
53 => 31.89
66 => 36.23
79 => 39.40
92 => 44.75
105 => 44.75

I want a php algorithm for the following issue

I have a multidimensional array like -
array(
"C" => array('A','A1','A2','B',B1'),
"C1" => array('A','A1','A2','B',B1'),
"A" => array('B','B1','C',C1'),
"B1" => array('A','A1','A2','C',C1'),
"B1" => array('A','A1','A2','C',C1'),
"A2" => array('B','B1','C',C1'),
"A1" => array('B','B1','C',C1')
);
I want a script which will assign a value out of the given array for each key,
Result will be like -
C A/A1/A2/B/B1 - A //I can assign any value from A/A1/A2/B/B1
C1 A/A1/A2/B/B1 - A1 //Once A is assigned for the above key then C1 will get value from A1/A2/B/B1 skipping the 'A' which is assigned to key 'C'
A B/B1/C/C1 - B //Now A will get value from B/B1/C/C1
B1 A/A1/A2/C/C1 - A2 //B1 will get value from A2/C/C1
B A/A1/A2/C/C1 - C //Likewise all the values will be assigned uniquely
A2 B/B1/C/C1 - B1
A1 B/B1/C/C1 - C1
The condition is that an the same value will not be assigned to multiple keys i.e all the keys will have different value. (Check the above result to know what exactly needs to be assigned)
$data = array(
"C" => array('A','A1','A2','B','B1'),
"C1" => array('A','A1','A2','B','B1'),
"A" => array('B','B1','C','C1'),
"B1" => array('A','A1','A2','C','C1'),
"B" => array('A','A1','A2','C','C1'),
"A2" => array('B','B1','C','C1'),
"A1" => array('B','B1','C','C1')
);
$assigned = array();
$result = array();
foreach($data as $k => $v) {
for($i=0;$i<count($v);$i++) {
if (!in_array($v[$i],$assigned)) {
$assigned[] = $v[$i];
$result[$k] = $v[$i];
break;
}
}
}
var_dump($result);
output:
array(7) {
["C"]=>
string(1) "A"
["C1"]=>
string(2) "A1"
["A"]=>
string(1) "B"
["B1"]=>
string(2) "A2"
["B"]=>
string(1) "C"
["A2"]=>
string(2) "B1"
["A1"]=>
string(2) "C1"
}
this solution is not good enaugh ;) if you define C1 as array('A') then C1 will be without value, to prevent that you can try to check is there posibility to assign values in different configuration.
$data = array(
"C" => array('A','A1'),
"C1" => array('A'),
"A" => array('B','B1','C','C1'),
"B1" => array('A','A1','A2','C','C1'),
"B" => array('A','A1','A2','C','C1'),
"A2" => array('B'),
"A1" => array('B','B1','C','C1')
);
$assigned = array();
$keys = array_keys($data);
for($i=0;$i<count($keys);$i++) {
getValue($data, $assigned, $keys, $i);
}
function getValue($data, &$assigned, $keys, &$i, $x = null) {
$j = $x === null ? 0 : array_search($x, $data[$keys[$i]]) +1;
for($j; $j<count($data[$keys[$i]]); $j++) {
$v = $data[$keys[$i]][$j];
if(!in_array($v, $assigned)) {
$assigned[$keys[$i]] = $v;
return;
}
}
$i--;
if ($i < 0) {
throw new Exception('no solutions');
}
$val = $assigned[$keys[$i]];
$assigned[$keys[$i]] = null;
getValue($data, $assigned, $keys, $i, $val);
}
var_dump($assigned);

Categories