Find maximum value in associative array - php

I have a associative array:
$users[0] = array('name' => 'Jim', 'depth' => '1', 'bk_id' => '9');
$users[1] = array('name' => 'Jill', 'depth' => '3', 'bk_id' => '10');
$users[2] = array('name' => 'Jack', 'depth' => '7', 'bk_id' => '17');
I would like to know a way of finding the array index with the maximum or greatest depth value?
Any suggestion is most appreciated.

Just iterate and look at the maximum value:
var max = 0, maxIndex = -1;
for(var i=0;i<users.length;i++) {
if(parseInt(users[i].depth,10) > max) {
max = users[i].depth;
maxIndex = i;
}
}
console.log("Your maximum depth is %d at index %d", max, maxIndex);

From PHP:
$index = 0;
$max = 0;
for ($i = 0; $i < count($users); $i++) {
if ($users[$i]['depth'] > $max) {
$max = $users[$i]['depth'];
$index = $i;
}
}
echo $users[$index]['name'] . ' has the greatest depth.';

Since the question is unclear, here's how to find it with PHP.
foreach ($users as $index => $user) {
if (!isset($maxdepth)) {
$maxdepth = $user['depth'];
$maxindex = $index;
}
else {
if ($user['depth']) > $maxdepth) {
$maxindex = $index;
$maxdepth = $user['depth'];
}
}
echo "Index: $maxindex";

You can either iterate over all the key-value pairs looking at the depth value each time, or sort the $users array using a custom sort function like sort_func(){ return a.depth - b.depth}

Using native sort function?
function getDeepestItem(arr)
{
arr.sort(function(a,b){return a['depth'] < b['depth'];});
return arr[0]
}

Related

Shuffle only same value associative array in PHP

My array is
$rank = [
'20' => 1,
'30' => 1,
'40' => 2,
'50' => 2,
'60' =>3,
];
expected op
$rank = ['30' => 1,'20' => 1,'50' => 2,'40' => 2,'60' =>3];
I want ranking random means only rank 1(value) should shuffle, later rank 2 should shuffle. later 3 and so on.. how to do it this in PHP?
function shuffle_array($list) {
if (!is_array($list)) return $list;
$keys = array_keys($list);
shuffle($keys);
$random = array();
foreach ($keys as $key) {
$random[$key] = $list[$key];
}
return $random;
}
echo "<pre>"; print_r(shuffle_array($rank));
First step can be to collect all values(say roll numbers) in an array( say a set) grouped by ranks nicely.
Now, get all the unique ranks from your array.
Sort the ranks(skip this step and just run a for loop starting from 1 if ranks are sequential).
Loop over this unique ranks and get all roll numbers according to the rank in hand.
Shuffle() them and add all of them to your result.
Snippet:
<?php
function getRandomizedSortedData($ranks){
$rank_set = [];
foreach($ranks as $roll_no => $rank){
if(!isset($rank_set[ $rank ])){
$rank_set[$rank] = [];
}
$rank_set[$rank][] = $roll_no;
}
$unique_ranks = array_unique($ranks);
sort($unique_ranks);
$result = [];
foreach($unique_ranks as $rank){
$roll_nos = $rank_set[$rank];
shuffle($roll_nos);
foreach($roll_nos as $roll_no){
$result[$roll_no] = $rank;
}
}
return $result;
}
Demo: http://sandbox.onlinephpfunctions.com/code/86c0ead227a06dda5c048dc9316c53788838bd65
you can use php function array_filter():
$rank = [
'20' => 1,
'30' => 2,
'40' => 3,
'50' => 2,
'60' => 1,
];
function filterRank1($value) {
return $value === 1;
}
function filterRank2($value) {
return $value === 2;
}
...
$rank1 = array_filter($rank, 'filterRank1');
$rank2 = array_filter($rank, 'filterRank2');
...

PHP - add values to already existing array

I have a already defined array, containing values just like the one below:
$arr = ['a','b','c'];
How could one add the following using PHP?
$arr = [
'a' => 10,
'b' => 5,
'c' => 21
]
I have tried:
$arr['a'] = 10 but it throws the error: Undefined index: a
I am surely that I do a stupid mistake.. could someone open my eyes?
Full code below:
$finishes = []; //define array to hold finish types
foreach ($projectstages as $stage) {
if ($stage->finish_type) {
if(!in_array($stage->finish_type, $finishes)){
array_push($finishes, $stage->finish_type);
}
}
}
foreach ($projectunits as $unit) {
$data[$i] = [
'id' => $unit->id,
'project_name' => $unit->project_name,
'block_title' => $unit->block_title,
'unit' => $unit->unit,
'core' => $unit->core,
'floor' => $unit->floor,
'unit_type' => $unit->unit_type,
'tenure_type' => $unit->tenure_type,
'floors' => $unit->unit_floors,
'weelchair' => $unit->weelchair,
'dual_aspect' => $unit->dual_aspect
];
$st = array();
$bs = '';
foreach ($projectstages as $stage) {
$projectmeasure = ProjectMeasure::select('measure')
->where('project_id',$this->projectId)
->where('build_stage_id', $stage->id)
->where('unit_id', $unit->id)
->where('block_id', $unit->block_id)
->where('build_stage_type_id', $stage->build_stage_type_id)
->first();
$st += [
'BST-'.$stage->build_stage_type_id => ($projectmeasure ? $projectmeasure->measure : '0')
];
if (($stage->is_square_meter == 0) && ($stage->is_draft == 0)) {
$height = ($stage->height_override == 0 ? $unit->gross_floor_height : $stage->height_override); //08.14.20: override default height if build stage type has it's own custom height
$st += [
'BST-sqm-'.$stage->build_stage_type_id => ($projectmeasure ? $projectmeasure->measure * $height: '0')
];
if ($stage->finish_type) {
$finishes[$stage->finish_type] += ($projectmeasure ? $projectmeasure->measure * $height: '0') * ($stage->both_side ? 2 : 1); //error is thrown at this line
}
} else {
if ($stage->finish_type) {
$finishes[$stage->finish_type] += ($projectmeasure ? $projectmeasure->measure : '0');
}
}
}
$data[$i] = array_merge($data[$i], $st);
$data[$i] = array_merge($data[$i], $finishes[$stage->finish_type]);
$i++;
}
The above code is used as is and the array $finishes is the one from the first example, called $arr
You're using += in your real code instead of =. That tries to do maths to add to an existing value, whereas = can just assign a new index with that value if it doesn't exist.
+= can't do maths to add a number to nothing. You need to check first if the index exists yet. If it doesn't exist, then assign it with an initial value. If it already exists with a value, then you can add the new value to the existing value.
If you want to convert the array of strings to a collection of keys (elements) and values (integers), you can try the following:
$arr = ['a','b','c'];
$newVals = [10, 5, 21];
function convertArr($arr, $newVals){
if(count($arr) == count($newVals)){
$len = count($arr);
for($i = 0; $i < $len; $i++){
$temp = $arr[$i];
$arr[$temp] = $newVals[$i];
unset($arr[$i]);
}
}
return $arr;
}
print_r(convertArr($arr, $newVals));
Output:
Array ( [a] => 10 [b] => 5 [c] => 21 )

Php weak random value generator for cases where repeated values are useful

I am generating test data for use in my frontend and I want to generate ages. Currently I am generating age between 18 and 100 using rand(1,100) like this:
require_once 'vendor/autoload.php';
$faker = Faker\Factory::create();
$superstars = array("Adam Cole","Finn Balor","Pete Dunne","Jordan Devlin","Noam Dar");
$fan_favourite_superstar_name = $superstars[ mt_rand( 0, count($superstars) -1 ) ];
$cities = array("London","Manchester","Leeds","Bristol");
$fan_location = $cities[ mt_rand( 0, count($cities) -1 ) ];
$the_models = array("Iphone","Nokia","Huawei","Samsung");
$fan_phone_model = $the_models[ mt_rand( 0, count($the_models) -1 ) ];
$array = Array (
"0" => Array (
"id" => uniqid(),
"fan_favourite_superstar_name" => $fan_favourite_superstar_name,
"fan_location" => $fan_location,
"fan_phone_model" => $fan_phone_model,
"fan_name" => $faker->name,
"fan_age" => rand(18,100),
"fan_comments" => $faker->text,
"fan_picture" => rand(1,500),
"last_updated" => time() + rand(1,1000),
),
However, I would like my ages to repeat although not completely. Is there a weak randomness generator apart from rand that can ensure that the an ages generated randomly repeat themselves n times?.
Here is a function just to show my suggestion of solution:
function getAge($start = 18, $end = 100, $repeat = 20){
$result = null;
static $ages = array();
if ( empty($ages) ) {
for ($i= $start; $i <= $end; $i++) {
for($j = 0; $j < $repeat; $j++)
$ages[] = $i;
}
}
$index = rand(0, count($ages));
$result = $ages[ $index ];
unset($ages[ $index ]);
$ages = array_values($ages);
return $result;
}

JSON encoding from wordpress database values

I need a proper JSON file with "geo_langitude", "geo_latitude", "adress" & "url" values
I have wp database with post_meta "property" - "geo_langitude" "geo_latitude" & "address" in there.
my file is smth like that
<?php
function return_markers($count) {
$query = new WP_Query('post_type=property&posts_per_page=-1&orderby=menu_order&order=DESC&post_status=publish');
$array = array();
$i = 0;
for ($i = 0; $i< $count; $i++) {
$elem = array(
't' => 'string '.$i,
'x' => get_post_meta($post->ID,'geo_latitude',true),
'y' => get_post_meta($post->ID,'geo_longitude',true),
'z' => $i
);
$array[] = $elem;
}
echo json_encode($elem);
};
return_markers($i);
?>
It's my first time using JSON so I have troubles and I don't know where. =(
with random markers work perfectly:
<?php
function return_markers($count) {
$array = array ();
for ($i = 0; $i< $count; $i++) {
$elem = array(
't' => 'string '.$i,
'x' => 23 + (rand ( 0 , 10000 ) / 10000) * 5,
'y' => 56.2 + (rand ( 0 , 10000 ) / 10000) * 0.8,
'url' => '#map_redirect_'.$i,
'z' => $i
);
$array[] = $elem;
}
echo json_encode($array);
};
return_markers(23);
?>

Convert multidimensional array to nested set array

im having a little problem i need some help with.
Im trying to convert a multidimensional array into a flatten array with nested set values right and left like so:
$array = {
'id' => 1
'name' => 'john'
'childs' => array(
array(
'id' => 1
'name' => 'jane'
)
)
}
to
$array = {
array(
'id' => 1,
'name' => 'john'
'left' => '1'
'right' => '4'
),
array(
'id' => 1,
'name' => 'jane'
'left' => '2'
'right' => '3'
)
}
Any help is appreciated!
I asked a very similar question and got a result, so thought I'd send it on for you. I realise this is quite an old topic, but still worth getting an answer. I've included my data, but would be easily adapted for yours.
$JSON = '[{"id":1,"children":[{"id":2,"children":[{"id":3},{"id":4}]},{"id":5}]}]';
$cleanJSON = json_decode($JSON,true);
$a_newTree = array();
function recurseTree($structure,$previousLeft)
{
global $a_newTree; // Get global Variable to store results in.
$indexed = array(); // Bucket of results.
$indexed['id'] = $structure['id']; // Set ID
$indexed['left'] = $previousLeft + 1; // Set Left
$lastRight = $indexed['left'];
$i_count = 0;
if ($structure['children'])
{
foreach ($structure['children'] as $a_child)
{
$lastRight = recurseTree($structure['children'][$i_count],$lastRight);
$i_count++;
}
}
$indexed['right'] = $lastRight + 1; // Set Right
array_push($a_newTree,$indexed); // Push onto stack
return $indexed['right'];
}
recurseTree($cleanJSON[0],0);
print_r($a_newTree);
function restructRecursive($array, $left = 1) {
if (isset($array['childs'])) {
$result = array();
foreach ($array['childs'] as $child) {
$result = array_merge($result, restructRecursive($child, $left+1));
}
unset($array['childs']);
}
$array['left'] = $left;
return array_merge(array($array), $result);
}
$newStruct = restructRecursive($oldStruct);
For anyone coming here and looking for a solution, loneTraceur's solution works fine. However, I needed one in OOP, so here is my version of it.
<?php
class NestedSet
{
protected $tree = [];
public function deconstruct($tree, $left = 0)
{
$this->flattenTree($tree, $left);
return $this->tree;
}
protected function flattenTree($tree, $left)
{
$indexed = [];
$indexed['id'] = $tree['id'];
$indexed['_lft'] = $left + 1;
$right = $indexed['_lft'];
if (isset($tree['children']) && count($tree['children'])) {
foreach ($tree['children'] as $child) {
$right = $this->flattenTree($child, $right);
}
}
$indexed['_rgt'] = $right + 1;
$this->tree[] = $indexed;
return $indexed['_rgt'];
}
}
You would run it like this:
$NestedSet = new NestedSet;
$flat = $NestedSet->deconstruct($tree):
This code is based on the other answer.

Categories