I have a multidimensional array as follows, which is a PHP array of shoe sizes and their conversions...
$size_array = array(
"M"=>array(
'6'=> array('uk'=>'6','eu'=>'39.5','us'=>'7'),
'6H'=> array('uk'=>'6.5','eu'=>'40','us'=>'7.5'),
'7'=> array('uk'=>'7','eu'=>'40.5','us'=>'8'),
'7H'=> array('uk'=>'7.5','eu'=>'41','us'=>'8.5'),
'8'=> array('uk'=>'8','eu'=>'42','us'=>'9'),
'8H'=> array('uk'=>'8.5','eu'=>'42.5','us'=>'9.5'),
'9'=> array('uk'=>'9','eu'=>'43','us'=>'10'),
'9H'=> array('uk'=>'9.5','eu'=>'44','us'=>'10.5'),
'10'=> array('uk'=>'10','eu'=>'44.5','us'=>'11'),
'10H'=> array('uk'=>'10.5','eu'=>'45','us'=>'11.5'),
'11'=> array('uk'=>'11','eu'=>'46','us'=>'12'),
'11H'=> array('uk'=>'11.5','eu'=>'46.5','us'=>'12.5'),
'12'=> array('uk'=>'12','eu'=>'47','us'=>'13'),
'12H'=> array('uk'=>'12.5','eu'=>'48','us'=>'13.5'),
'13'=> array('uk'=>'13','eu'=>'48.5','us'=>'14')
),
"F"=>array(
'3'=> array('uk'=>'3','eu'=>'35.5','us'=>'5'),
'3H'=> array('uk'=>'3.5','eu'=>'36','us'=>'5.5'),
'4'=> array('uk'=>'4','eu'=>'37','us'=>'6'),
'4H'=> array('uk'=>'4.5','eu'=>'37.5','us'=>'6.5'),
'5'=> array('uk'=>'5','eu'=>'38','us'=>'7'),
'5H'=> array('uk'=>'5.5','eu'=>'38.5','us'=>'7.5'),
'6'=> array('uk'=>'6','eu'=>'39','us'=>'8'),
'6H'=> array('uk'=>'6.5','eu'=>'39.5','us'=>'8.5'),
'7'=> array('uk'=>'7','eu'=>'40','us'=>'9'),
'7H'=> array('uk'=>'7.5','eu'=>'41','us'=>'9.5'),
'8'=> array('uk'=>'8','eu'=>'41.5','us'=>'10'),
'8H'=> array('uk'=>'8.5','eu'=>'42.5','us'=>'10.5'),
'9'=> array('uk'=>'9','eu'=>'43','us'=>'11'),
'9H'=> array('uk'=>'9.5','eu'=>'43.5','us'=>'11.5'),
'10'=> array('uk'=>'10','eu'=>'44','us'=>'12')
)
);
The array is part of a function that returns the conversions based on a supplied size and gender (i.e. SizeConvert('M','6') returns Array ([uk] => 6, [eu] => 39.5,[us] => 7)).
I want to extend the function to allow the passing of a value which will return the array results with any .5 values replaced with ½ (or ½) (i.e. SizeConvert('M','6','Y') returns Array ([uk] => 6, [eu] => 39½,[us] => 7))
How do I make str_replace (or a more appropriate command) iterate over the array and replace the values?
I've tried something like str_replace(".5", "½", $size_array) but I guess that's not working as it's only looking at the initial array, not the sub-arrays.
You are trying to apply this to a multidimensional array without real reason. If you have your SizeConvert function ready and returning a one dimensional array, simply apply the transformation before returning the value:
function SizeConvert(/* other parameters */, bool $convertOneHalf) {
$match = ... // your code to find the match
return $convertOneHalf
? str_replace('.5', '½', $match)
: $match;
}
Based on the boolean value of the parameter that dictates whether the conversion should be applied, we either return the modified or the unmodified result through the ternary.
Do not overthink it and use a for loop to loop through all the elements in the array and use an if...else... to check for 0.5
if($array[index]=="0.5") {
$array[index]="½";
} else {
$array[index]=str_replace(".5", "½", $array[index]);
}
I coded up a simple code, it's not exactly the answer to your question but u can use the logic behind it. The code below will change all the 0.5 in the array to 1⁄2 but since u already acquire the data, there is no need to have so much nested-loop, just 1 level of the loop to loop through all ur elements in your array is enough.
<?php
$size_array = array(
"M" => array(
'6' => array(
'uk' => '6',
'eu' => '39.5',
'us' => '7'
) ,
'6H' => array(
'uk' => '6.5',
'eu' => '40',
'us' => '7.5'
) ,
'7' => array(
'uk' => '7',
'eu' => '40.5',
'us' => '8'
)
) ,
"F" => array(
'3' => array(
'uk' => '3',
'eu' => '35.5',
'us' => '5'
) ,
'3H' => array(
'uk' => '3.5',
'eu' => '36',
'us' => '5.5'
) ,
'4' => array(
'uk' => '4',
'eu' => '37',
'us' => '6'
)
)
);
foreach ($size_array as $firstLevel)
{
foreach ($firstLevel as $secondLevel)
{
foreach ($secondLevelas $values)
{
if ($values== "0.5")
{
echo $values= "½";
}
else
{
echo $values= str_replace(".5", "½", $values);
}
}
}
}
?>
I have a rating system on my Wordpress that came with the theme. The maximum rating possible is 10, so I wanted to edit this and make a 100 possible rating.
So I edited this part:
public static function max_rating( $listing_id = null ) {
$default = 100;
So now it understands that the max possible rating is 100.
But under the rating array, there were these lines:
$rating_options = array(
'1' => 1,
'2' => 2,
'3' => 3,
'4' => 4,
'5' => 5,
'6' => 6,
'7' => 7,
'8' => 8,
'9' => 9,
'10' => 10,
Which understand that the maximum possible rating is 10. Now I want to make a maximum rating of 100, but adding '11' => 11, '12' => 12, '13' => 13 etc takes a lot of time and it consumes a lot of space in my file. Is there a possiblity to shorten this or do I really have to enter every rating up to 100?
The accepted answer points you in the right direction.
Additional I would advice using array_combine like so:
$range = range(1,100);
$rating_options = array_combine($range, $range);
// array(1=>1, 2=>2, ...)
This way, your keys will be the same as the values.
you can use PHP's range function:
$ratings = range(0, 100);
reference: https://secure.php.net/manual/en/function.range.php
I have an array with key and value pair. I'm building this array dynamically and below is the code.
$x[] = array('type_name' => $value->name,
'percentage'=> intval($percentage));
My intention is to get the maximum value and for that I do
max($x);
However it is returning the wrong value actually the lowest value. Following is my array. Any help would be awesome.
$x = array(
array(
'type_name' => 'type 1'
'percentage' => 10,
),
array(
'type_name' => 'type 2'
'percentage' => 15,
),
array(
'type_name' => 'type 3'
'percentage' => 45,
),
);
Thanks is advance.
From php max() documentation :
// Multiple arrays of the same length are compared from left to right
It means that if you want to compare "percentage" values first instead of "type_name" values, you'll have to change their order in the array.
So, you could build your array like this ("percentage" comes first) and it should work :
$x[] = array(
'percentage'=> intval($percentage),
'type_name' => $value->name
);
For example :
$x = array(
array(
'percentage' => 10,
'type_name' => 'type 1'
),
array(
'percentage' => 15,
'type_name' => 'type 2'
),
array(
'percentage' => 45,
'type_name' => 'type 3'
),
array(
'percentage' => 25,
'type_name' => 'type 4'
)
);
print_r(max($x));
Output :
Array
(
[percentage] => 45
[type_name] => type 3
)
Hope it helps.
You need to read how the max compares against different types of data. In your case, you are trying to compare against one of the array item i.e. percentage inside one of the item so the function max does not know to do this.
There is an example by Revo in the manual which shows you how to do this.
You are creating an array of arrays. max doesn’t know that your arrays should be compared by the 'percentage' key, so it can’t be used here.
Instead, find the maximum value yourself. For example, like this:
$maxPercentage = false;
foreach ($x as $item) {
if ($maxPercentage === false || $item['percentage'] > $maxPercentage) {
$maxPercentage = $item['percentage'];
}
}
Now, $maxPercentage will store maximum percentage. Of, if you want an item with maximum percentage, get it like this:
$maxPercentage = false;
$maxItem = false;
foreach ($x as $item) {
if ($maxPercentage === false || $item['percentage'] > $maxPercentage) {
$maxPercentage = $item['percentage'];
$maxItem = $item;
}
}
Having this array :
array (size=1)
24 =>
array (size=7)
'user_id' => int 24
'date_clicked' =>
array (size=3)
0 => int 1382867319
1 => int 1382867419
2 => int 1382940698
'ip' => string '127.0.0.1' (length=9)
'email' => string 'test' (length=8)
'name' => string 'test' (length=7)
'request' => string 'test content' (length=12)
'faked_clicks' =>
array (size=3)
0 => int 1382867319
1 => int 1382867419
2 => int 1382940698
Here is my implementation that adds the faked_clicks array based on the date clicked array :
foreach($parsedUserClicks as $k => $v) {
foreach($v['date_clicked'] as $kk => $vv) {
$rangeHigh = range($vv, $vv+(60*60*24));
$checkHigh = array_intersect($v['date_clicked'], $rangeHigh );
if(count($checkHigh) >= 3) {
$parsedUserClicks[$k]['faked_clicks'] = $checkHigh;
}
}
}
The thing is that , by using array_intersect , it's taking quite a long time make a search only for 3 timestamps .
What I want to achieve is to get all 3 dates that are in an interval of 1 day . But my search is too slow (5 seconds for this simple search) . Any algorith i could use for this type of search ?
P.S. : I know i should not use such a big range to intersect arrays (60*60*24) . But i can't seem to find another solution . Also the range might get bigger so this method eventually will drop .
how about simply checking the values?
$dc_copy = $v['date_clicked'];
foreach($parsedUserClicks as $k => $v) {
$checkHigh = array();
foreach($v['date_clicked'] as $kk => $vv) {
$rangeHigh = $vv+(60*60*24);
foreach($dc_copy as $v2){
if($v2 >= $vv && $v2 <= $rangeHigh){
$checkHigh[] = $v2;
}
}
if(count($checkHigh) >= 3) {
$parsedUserClicks[$k]['faked_clicks'] = $checkHigh;
}
}
}
The only solution i could think of right now was to minimize the search to be made on days not on seconds . This is not a final answere , maybe someone else can give a proper search algorith for this type of search .
I'm trying to multisort a DB array based on the users status. Those with Status = 1 go at the top, those with Status = 0 go at the bottom of the array. I thought I had it working but it just stopped today with the addition of new rows to the DB.
uasort($ven, function ($a, $b) { return $a['v_status'] == '1' ? false : true; });
It's a simple DB array from MySQL:
Array (
[0] => array(
[name] => '',
[v_status] => 0
[1] => array(
[name] => '',
[v_status] => 1
)
As mentioned in comments to my other answer, splitting the array into active/inactive arrays could be a better solution than sorting.
$items = array(
array('name' => 'active1', 'active' => '1'),
array('name' => 'inactive1', 'active' => '0'),
array('name' => 'active2', 'active' => '1'),
array('name' => 'inactive2', 'active' => '0'),
array('name' => 'inactive3', 'active' => '0'),
array('name' => 'active3', 'active' => '1'),
array('name' => 'inactive4', 'active' => '0'),
);
$active = array_filter($items, function($item){ return $item['active'] == '1'; });
echo '<pre>' . print_r($active,true);
// You could filter again here, not sure which would be quicker,
// but my guess would be the array_diff method (which also ensures
// that no items get filtered out by both filters)
$inactive = array_diff_key($items, $active);
echo '<pre>' . print_r($inactive,true);
uasort expects the callback to return a positive integer if $a should be above $b, a negative integer if $b should be above $a or 0 if they are equal.
This is why despite there only being 2 options Jon's suggestion return $b['v_status'] - $a['v_status']; is correct.
In your case if at some point during the sort $a[v_status] = 0 and $b[v_status] = 1 the function looks at $a[v_status], returns false, which equates to 0 and the algorithm (quick sort I think) treats them as equal and therefore leaves them in their current order.
See PHP: usort for reference, which expects a similar callback.