Issue about correct and fast seeking in array - php

I have a question about correct and fast seeking in php array.
I have input array:
array (size=2)
0 =>
array (size=7)
'Videos' =>
array (size=2)
240 =>
array (size=2)
...
120 =>
array (size=2)
...
'Texts' =>
array (size=0)
empty
'Price' => float 0
'QaAudio' => int 1
'QaVideo' => int 3
'Level' => string 'normal' (length=6)
'PreviewPic' =>
array (size=7)
40 =>
array (size=12)
...
60 =>
array (size=12)
...
140 =>
array (size=12)
...
160 =>
array (size=12)
...
320 =>
array (size=12)
...
640 =>
array (size=12)
...
1024 =>
array (size=12)
...
1 =>
array (size=7)
'Videos' =>
array (size=3)
480 =>
array (size=2)
...
360 =>
array (size=2)
...
120 =>
array (size=2)
...
'Texts' =>
array (size=0)
empty
'Price' => float 0
'QaAudio' => int 1
'QaVideo' => int 3
'Level' => string 'sexy' (length=4)
'PreviewPic' =>
array (size=7)
40 =>
array (size=12)
...
60 =>
array (size=12)
...
140 =>
array (size=12)
...
160 =>
array (size=12)
...
320 =>
array (size=12)
...
640 =>
array (size=12)
...
1024 =>
array (size=12)
...
I need to find in it the video, that has max value in Videos key.(it has 360,240,120 values as you can see in example) and has Level Key that equal to 'normal' or 'sexy' value.
I wrote some method to do it:
public function getPresentationVideo($id)
{
$result = [];
$notHardVideos = [];
$profileVideos = $this->getProfilesVideos($id,0,50);
if ($profileVideos && count($profileVideos) > 0) {
foreach ($profileVideos as $video) {
if (in_array($video['Level'],['normal','sexy'])) {
$video['maxVideoQuality'] = max(array_keys($video['Videos']));
$notHardVideos[] = $video;
}
}
$keyForMaxQuality = 0;
if (count($notHardVideos) > 1) {
$maxQuality = 0;
foreach($notHardVideos as $key => $video) {
if($video['maxVideoQuality'] > $maxQuality)
{
$maxQuality = $video['maxVideoQuality'];
$keyForMaxQuality = $key;
}
}
}
if (count($notHardVideos) > 0) {
$result = $notHardVideos[$keyForMaxQuality];
unset($result['maxVideoQuality']);
}
}
return $result;
}
It do it well.
But i wonder is there any more effective way to do it.
Do you have any ideas?
Thanks in advance.

$result = array_reduce($videos, function ($result, array $video) {
if (!in_array($video['Level'], ['normal', 'sexy'])) {
return $result;
}
if (!$result) {
return $video;
}
if (max(array_keys($video['Videos'])) > max(array_keys($result['Videos']))) {
return $video;
}
return $result;
});
This will return the sub array which has a 'normal' or 'sexy' level (BTW, FTW?!) and which has the highest key in its 'Videos' sub array. It doesn't include any other considerations, as you seem to have in your code, because you did not specify exactly what those considerations are. However, you should get the idea and can add more checks if you need.
See http://php.net/array_reduce for help with this function. In short, this takes each element in the array in turn and compares it to the previous best candidate. I.e., $result will be nothing at first, but when you have found a 'normal' or 'sexy' video it will become that video, and on subsequent calls the video with the higher keys will win.

Related

How to remove doubles element in foreach loop and keep date assigned to original?

What I am trying to get is to remove duplicate values in the Rest field, but I want to assign / keep its date in the original. element:
array (size=413)
0 =>
array (size=5)
'Date' =>
array (size=1)
0 => int 1588520980
'Rest' => 123abc
1 =>
array (size=5)
'Date' =>
array (size=1)
0 => int 1588520981
'Rest' => qwe123
2 =>
array (size=5)
'Date' =>
array (size=1)
0 => int 1588520983
'Rest' => qwe123
I try it but it doesn't work
public function find_repeats($arr)
{
foreach(array_column($arr, 'Rest') as $ckey=>$value) {
$keys = array_reverse(array_keys(array_column($arr, 'Rest'), $value));
foreach ($keys as $v) {
if ($ckey != $v && isset($arr[$v]))
{
$arr[$ckey]['Date'][] = $arr[$v]['Date'][0];
unset($arr[$v]);
}
}
}
return $arr;
}
This is what the table should look like after this operation
array (size=413)
0 =>
array (size=5)
'Date' =>
array (size=1)
0 => int 1588520980
'Rest' => 123abc
1 =>
array (size=5)
'Date' =>
array (size=1)
0 => int 1588520981
1 => int 1588520983
'Rest' => qwe123
Thanks for help! :)
Simple solution without all these stacked functions:
$newData = [];
foreach ($arr as $item) {
$rest = $item['Rest'];
if (!isset($newData[$rest])) {
$newData[$rest] = $item;
} else {
$newData[$rest]['Date'][] = $item['Date'][0];
}
}
// optionally apply array_values to get 0-indexed array:
$newData = array_values($newData);

How to store a binary tree as one-dimensional array?

How to construct data into a binary tree sort to output a one-dimensional array?
Now that I have constructed the data into a binary tree, how can I recursively solve the binary tree as a one-dimensional array with the following code and data:
Data
$nodes = array(8,3,10,1,6,14,4,7,13);
Construct a binary tree code
function insertNode($node,$newNode){
//var_dump($node);
//var_dump($newNode);
//exit;
if ($node['key'] < $newNode['key']){
if (empty($node['right'])){
$node['right'] = $newNode;
}else{
$node['right'] = insertNode($node['right'],$newNode);
}
}elseif ($node['key'] > $newNode['key']){
if (empty($node['left'])){
$node['left'] = $newNode;
}else{
$node['left'] = insertNode($node['left'],$newNode);
}
}
return $node;
}
function tree($nodes)
{
$node = [
'key' => '',
'left' => '',
'right' => ''
];
$newNode = [
'key' => '',
'left' => '',
'right'=> ''
];
foreach ($nodes as $key => $value){
//insert($value,$key);
if($key == 0)
{
$node['key'] = $value;
continue;
}
$newNode['key'] = $value;
//Constructing a binary tree
$node = insertNode($node,$newNode);
}
//Recursive solution
$node = midSortNode($node);
return $node;
}
var_dump(tree($nodes));
The following is my constructed binary tree
array (size=3)
'key' => int 8
'left' =>
array (size=3)
'key' => int 3
'left' =>
array (size=3)
'key' => int 1
'left' => string '' (length=0)
'right' => string '' (length=0)
'right' =>
array (size=3)
'key' => int 6
'left' =>
array (size=3)
...
'right' =>
array (size=3)
...
'right' =>
array (size=3)
'key' => int 10
'left' => string '' (length=0)
'right' =>
array (size=3)
'key' => int 14
'left' =>
array (size=3)
...
'right' => string '' (length=0)
I need to recursively classify the binary tree into a well-ordered one-dimensional array.
My code is as follows
function midSortNode($node){
$sortArr = [];
if (!empty($node)){
$sortArr[] = midSortNode($node['left']);
//$sortArr['left'] = midSortNode($node['left']);
array_push($sortArr,$node['key']);
$sortArr[] = midSortNode($node['right']);
//$sortArr['right'] = midSortNode($node['right']);
}
return $sortArr;
}
var_dump(midSortNode($node));
Here is the result, but not what I want
0 =>
array (size=3)
0 =>
array (size=3)
0 =>
array (size=0)
...
1 => int 1
2 =>
array (size=0)
...
1 => int 3
2 =>
array (size=3)
0 =>
array (size=3)
...
1 => int 6
2 =>
array (size=3)
...
1 => int 8
2 =>
array (size=3)
0 =>
array (size=0)
empty
1 => int 10
2 =>
array (size=3)
0 =>
array (size=3)
...
1 => int 14
2 =>
array (size=0)
...
How to solve the binary tree as follows
array (size=9)
0 => int 1
1 => int 3
2 => int 4
3 => int 6
4 => int 7
5 => int 8
6 => int 10
7 => int 13
8 => int 14
I'm assuming that your happy with the steps so far, so the main code as it is isn't changed. All I think you need to do is to extract the data from the final tree into a 1 dimensional array. As the items are all leaf nodes and in order, you can just use array_walk_recursive() to go over all of the nodes and add them to a new array...
$tree = tree($nodes);
array_walk_recursive( $tree,
function ($data) use (&$output) { $output[] = $data;} );
print_r($output);
gives...
Array
(
[0] => 1
[1] => 3
[2] => 4
[3] => 6
[4] => 7
[5] => 8
[6] => 10
[7] => 13
[8] => 14
)
Edit:
To update the existing code to do this, you can change the midSortNode() to pass around the list of outputs and only add in the current node...
function midSortNode($node, $sortArr = []){
if (!empty($node)){
$sortArr = midSortNode($node['left'], $sortArr);
$sortArr[] = $node['key'];
$sortArr = midSortNode($node['right'], $sortArr);
}
return $sortArr;
}

how to replace or eliminate #xsi::nill => true in php multi dimensional arrays

I have a php array like this
print_r(myarray) is
Array ( [0] => Array ( [#xsi:nil] => true ) [1] => Array ( [#xsi:nil] => true ) [2] => Array ( [#xsi:nil] => true ) [3] => 'some value' [4] => Array ( [#xsi:nil] => true ))
I need to eliminate the values Array ( [#xsi:nil] => true ) or just to replace them with say "nill". I tried a lot, this being a nested array i couldnt get the key for the values [#xsi:nil] => true
How to check in php for the indexes which hold the value Array ( [#xsi:nil] => true )? and replace them with say 'nill'?
trial one :
$key1 = array_search(array('#xsi:nil'=>'true'), array_column($arrays, 'NOTE')); //to catch the indexes.
function searchMyCoolArray($arrays, $key, $search) {
$count = 0;
foreach($arrays as $object) {
if(is_object($object)) {
$ob1 = $object;
$object = get_object_vars($object);
$key1 = array_search(40489, array_column($arrays, 'uid'));
}
if(array_key_exists($key, $object) && $object[$key] == $search)
{
// print_r($first_names_note[$key]);
// echo "ffgfg ".$ob1[0]." rtrtrt";
// var_dump($object);
// print_r($arrays[$key]);
// echo $object;
// print_r($object);
// print_r($first_names_note)."<br>";
$count++;
//echo "sddsdsdsd";
}
}
return $count;
}
echo searchMyCoolArray($first_names_note, '#xsi:nil', 'true');
here i got the count correct, but it was not i need, I tried to get the indexs in the function itself, but failed
Please help, i googled alot pleeeeeeeeeeeeeeeeez
You may try to use array_walk to traverse the array and then unset all elements with the key #xsi:nil like this:
<?php
$arr = array(
array("#xsi:nil" => true),
array("#xsi:nil" => true),
array("#xsi:nil" => true),
array("some_value" =>4),
array("#xsi:nil" => true),
);
array_walk($arr, function(&$data){
if(is_array($data) && array_key_exists("#xsi:nil", $data)){
unset($data["#xsi:nil"]);
$data[] = "nil";
}
});
var_dump($arr);
// IF YOU WANT TO REMOVE ALL EMPTY ARRAYS COMPLETELY, JUST DO THIS:
$arr = array_filter($arr);
var_dump($arr);
// GET THE LENGTH OF THE FILTERED ARRAY.
$count = count($arr);
echo $count; //<== PRODUCES 5
// THE 1ST VAR_DUMP() PRODUCES:
array (size=5)
0 =>
array (size=1)
0 => string 'nil' (length=3)
1 =>
array (size=1)
0 => string 'nil' (length=3)
2 =>
array (size=1)
0 => string 'nil' (length=3)
3 =>
array (size=1)
'some_value' => int 4
4 =>
array (size=1)
0 => string 'nil' (length=3)
// THE 2ND VAR_DUMP() PRODUCES:
array (size=5)
0 =>
array (size=1)
0 => string 'nil' (length=3)
1 =>
array (size=1)
0 => string 'nil' (length=3)
2 =>
array (size=1)
0 => string 'nil' (length=3)
3 =>
array (size=1)
'some_value' => int 4
4 =>
array (size=1)
0 => string 'nil' (length=3)
Test it out HERE.
Cheers & Good Luck...
This is not the answer, the code for the answer was provided by #Poiz
Here is my complete code which i formatted
//my array
$arr = Array (Array ( '#xsi:nil' => 'true' ), Array ('#xsi:nil' => 'true' ), Array ( '#xsi:nil' => 'true' ) );
// print_r($arr);
//performed array walk
array_walk($arr, function(&$data){
if(is_array($data) && array_key_exists("#xsi:nil", $data)){
unset($data["#xsi:nil"]);
$data = "nil";
}
});
print_r($arr);
//OUTPUT : Array ( [0] => nil [1] => nil [2] => nil )

Laravel 5 adding an element in an array does not work

I am getting an array from table questions
$questions = Category::where('slug', $slug)->first()->questions->toArray();
then using foreach I iterate over array and push an array element during each iteration like below
foreach ($questions as $question) {
$question['options'] = Option::where('question_id', $question['id'])->get()->toArray();
}
Ideally I should get response like below
array (size=5)
0 =>
array (size=6)
'id' => int 1
'category_id' => int 1
'questions' => string 'The ozone layer restricts' (length=25)
'answer_id' => int 4
'image_path' => string '' (length=0)
'options' =>
array (size=4)
0 =>
array (size=3)
...
1 =>
array (size=3)
...
2 =>
array (size=3)
...
3 =>
array (size=3)
...
1 =>
array (size=6)
'id' => int 2
'category_id' => int 1
'questions' => string 'Ecology deals with' (length=18)
'answer_id' => int 10
'image_path' => string '' (length=0)
'options' =>
array (size=4)
0 =>
array (size=3)
...
1 =>
array (size=3)
...
2 =>
array (size=3)
...
3 =>
array (size=3)
...
but Actually I am not getting options key into my questions array
The issue here is when you do a foreach, you are referring to the array by value - that is, under the hood PHP will create a copy of the variable inside the array. What you need is to access each element in the foreach by reference (note the & next to $q)
foreach ($questions as & $q) {
$q['options'] = Option::where('question_id', '=', $q['id'])->get()->toArray();
}
See:
Passing by references and the PHP docs on foreach.
Note: This is not really a Laravel issue, just PHP.
Try this (& in foreach):
foreach ($questions as & $question) {
$question['options'] = Option::where('question_id', $question['id'])->get()->toArray();
}
You can try:
foreach ($questions as $key=>$question) {
$questions[$key]['options'] = Option::where('question_id',$question['id'])->get()->toArray();
}

php Get all values from multidimensional associative array

how can i get all values from multidimensional associative array
I dont want to use print_r want to control my array put all the value in normal array with unique values
my array is look like this
array (size=10)
0 =>
array (size=3)
0 =>
array (size=1)
'Campaign' => string 'DEMO' (length=4)
1 =>
array (size=1)
'Campaign' => string 'Home_Sec' (length=8)
2 =>
array (size=1)
'Campaign' => string '' (length=0)
1 =>
array (size=0)
empty
2 =>
array (size=0)
empty
3 =>
array (size=1)
0 =>
array (size=1)
'Campaign' => string 'Back_Brace' (length=10)
4 =>
array (size=2)
0 =>
array (size=1)
'Campaign' => string 'Home_Sec' (length=8)
1 =>
array (size=1)
'Campaign' => string '' (length=0)
5 =>
array (size=1)
0 =>
array (size=1)
'Campaign' => string 'home_Sec_2' (length=10)
6 =>
array (size=1)
0 =>
array (size=1)
'Campaign' => string 'Burial_Ins' (length=10)
7 =>
array (size=0)
empty
8 =>
array (size=0)
empty
9 =>
array (size=0)
empty
I dont want to use print_r want to control my array put all the value in normal array with unique values
array_walk is an option, but here's another option if you want to try something a bit more coded by yourself, solving this problem recursively
This will flatten any n-max level array into a single array that contains all the values of all the sub arrays (including the initial array itself)
<?php
$array = array(
1 => array(1, 2, 3, 4 => array(
1, 2, 3, 4
)),
4, 5);
function recurse_values($array) {
if (is_array($array)) {
$output_array = array();
foreach ($array as $key=>$val) {
$primitive_output = recurse_values($val);
if (is_array($primitive_output)) {
$output_array = array_merge($output_array, $primitive_output);
}
else {
array_push($output_array, $primitive_output);
}
}
return $output_array;
}
else {
return $array;
}
}
print_r(recurse_values($array));
?>
If you need unique values, at the end you can add a array_unique to do this.
You can use array_walk
$array = array(...); //your values here
function output($item, $key) {
echo $key . ' =>' . $item;
}
array_walk($array, 'output');
Are you asking how you can "flatten" this multi-dimensional array into a one dimension? Possible solutions to similar problems... How to Flatten a Multidimensional Array?

Categories