Here is an example array I am attempting to sort:
$array = (object)array(
'this' => 'that',
'posts'=> array(
'title' => '001 Chair',
'title' => 'AC43 Table',
'title' => '0440 Recliner',
'title' => 'B419',
'title' => 'C10 Chair',
'title' => '320 Bed',
'title' => '0114'
),
'that' => 'this'
);
usort($array->posts, 'my_post_sort');
Here is the function I am using to sort:
function my_post_sort($a, $b) {
$akey = $a->title;
if (preg_match('/^[0-9]*$',$akey,$matches)) {
$akey = sprintf('%010d ',$matches[0]) . $akey;
}
$bkey = $b->title;
if (preg_match('/^[0-9]*$',$bkey,$matches)) {
$bkey = sprintf('%010d ',$matches[0]) . $bkey;
}
if ($akey == $bkey) {
return 0;
}
return ($akey > $bkey) ? -1 : 1;
}
This gives me the following results:
'posts', array(
'title' => 'C10 Chair',
'title' => 'B419',
'title' => 'AC43 Table',
'title' => '320 Bed',
'title' => '0440 Recliner',
'title' => '0114',
'title' => '001 Chair'
)
Now, the last step I need is getting the numbers to appear (descending) before the letters (descending).
Here is my desired output:
'posts', array(
'title' => '320 Bed',
'title' => '0440 Recliner',
'title' => '0114',
'title' => '001 Chair',
'title' => 'C10 Chair',
'title' => 'B419',
'title' => 'AC43'
)
I've tried all kinds of sorts, uasorts, preg_match, and other functions; and just cannot seem to figure out the last step.
Any suggestions or assistance? Thank you.
Try this comparing function:
function my_post_sort($a, $b) {
$akey = $a->title;
$bkey = $b->title;
$diga = preg_match("/^[0-9]/", $akey);
$digb = preg_match("/^[0-9]/", $bkey);
if($diga && !$digb) {
return -1;
}
if(!$diga && $digb) {
return 1;
}
return -strcmp($akey, $bkey);
}
It will sort in descending order, but place digits before other symbols.
First of all, I do not think your array can works... You can not have the same key many times on the same array level.
foreach ($array as $key => $title) {
if ( is_numeric(substr($title, 0, 1)) ) {
$new_array[$key] = $title;
}
}
array_multisort($array, SORT_DESC, SORT_STRING);
array_multisort($new_array, SORT_DESC, SORT_NUMERIC);
$sorted_array = array_merge($array, $new_array);
Related
My first array like this :
$photoList = array(
array(
'id' => 1,
'name' => 'chelsea.jpg'
),
array(
'id' => 2,
'name' => 'mu.jpg'
),
array(
'id' => 3,
'name' => 'city.jpg'
)
);
My second array like this :
photo = array('cover1'=>'liverpool.jpg', 'cover2'=>'city.jpg');
My code like this :
$photo = array_filter($photo, function($item) use ($photoList) {
return in_array($item, array_column($photoList, 'name')) ;
});
if (empty($photo))
$photo=null;
If I run : echo '<pre>';print_r($photo);echo '</pre>';, the result like this :
Array
(
[cover2] => city.jpg
)
I want the result like this :
Array
(
[cover1] => city.jpg
)
So if there is no cover1, the cover2 changed to be cover1
How can I do it?
You could re-index the keys like this :
$photoList = array(
array(
'id' => 1,
'name' => 'chelsea.jpg'
),
array(
'id' => 2,
'name' => 'mu.jpg'
),
array(
'id' => 3,
'name' => 'city.jpg'
)
);
$photo = array('cover1'=>'liverpool.jpg', 'cover2'=>'city.jpg');
$photo = array_filter($photo, function($item) use ($photoList) {
return in_array($item, array_column($photoList, 'name')) ;
});
if (empty($photo)){
$photo = null;
} else {
$idx = 1 ;
foreach ($photo as $key => $value) {
unset($photo[$key]);
$photo['cover'.$idx++] = $value;
}
}
print_r($photo);
Outputs :
Array
(
[cover1] => city.jpg
)
I'm not sure about what you really need. Assuming you want to do that recursively, I hope this helps:
$label = 'cover';
$index = 1;
$a_keys = array_keys($photo);
$new_photo = [];
foreach($a_keys AS $k=>$v){
$new_photo[$label.$index] = $photo[$k];
$index++;
}
$photo = $new_photo;
It will rewrite your array with wanted naming style.
I used ArrayDataProvider to mix models and then merged them into one data-provider. I used the data-provider in grid-view and everything is works fine.
But I need to order the grid-view by one column I tried a lot of solutions but none of them are worked.
This my model code (order by item_order )
public function getAllSelectedItemsInTheUnit($unitId, $grid = false)
{
$finalList = array();
$storiesList = array();
$activityList = array();
$breakList = array();
$stories = UnitStories::find()->joinWith(['story'])->where("unit_id=$unitId")->all();
if (count($stories) > 0) {
foreach ($stories as $item) {
$storiesList[] = [
'key' => self::TYPE_STORY . $item->id,
'id' => $item->id,
'title' => $item->story->title,
'type' => self::TYPE_STORY,
'item_order' => $item->unit_order,
];
}
}
$activities = UnitActivities::find()->joinWith(['activity'])->where("unit_id=$unitId")->all();
if (count($activities) > 0) {
foreach ($activities as $item) {
$activityList[] = [
'key' => self::TYPE_ACTIVITY . $item->id,
'id' => $item->id,
'title' => $item->activity->title,
'type' => self::TYPE_ACTIVITY,
'item_order' => $item->activity_order,
];
}
}
$breaks = UnitBreaks::find()->where("unit_id=$unitId")->all();
if (count($breaks) > 0) {
foreach ($breaks as $item) {
$breakList[] = [
'key' => self::TYPE_BREAK . $item->id,
'id' => $item->id,
'title' => $item->title,
'type' => self::TYPE_BREAK,
'item_order' => $item->unit_order,
];
}
}
$finalList = array_merge($storiesList, $activityList, $breakList);
$dataProvider = new ArrayDataProvider([
'allModels' => $finalList, 'key' => 'key',
'sort' => [
'attributes' => ['item_order'],
],
]);
return $dataProvider;
}
Any solution will be very good even sort array by pure PHP I guess will fix the problem .
You can use usort()
usort($finalList, function ($a, $b) {
return $a['item_order'] < $b['item_order'];
});
Add your condition in callback >, <, <= etc
how to check whether 4 exist or not in array at id key position
$arr = array(
array(
'id' => 1,
'other_data' => 'ganesh'
),
array(
'id' => 2,
'other_data' => 'ramesh'
),
array(
'id' => 3,
'other_data' => '4'
),
)
The array you provided is not a valid multi-dimensional array. You need to add commas after each array in the array. Below i use array_column and in_array without using foreach
<?php
$arr = array(
array(
'id' => 1,
'other_data' => 'ganesh'
),//add comma
array(
'id' => 2,
'other_data' => 'ramesh'
),
array(
'id' => 3,
'other_data' => '4'
),
);
$filtered = array_column($arr, 'id');//return the id column in this array
if(in_array(4, $filtered)){//check if 4 exists
echo '4 exists';
} else {
echo '4 does not exist';
}
?>
Quite simple, loop through the array and check if the value exists:
$value = 4;
$exists = false;
foreach($arr as $innerArr){
if($innerArr['id'] == $value){
$exists = true;
break;
}
}
If $exists is now true, the value exists within the array.
Try this one, and let me know if you face any problem.
<?php
$arr = array(
array(
'id' => 1,
'other_data' => 'ganesh'
),
array(
'id' => 2,
'other_data' => 'ramesh'
),
array(
'id' => 3,
'other_data' => '4'
)
);
foreach ($arr as $key => $value) {
if (in_array("4", $value))
{
$sub_index = $value['id'];
echo "Match found at $sub_index";
break;
}
}
Just gotta loop through your array and check existence through in_array() function.
you need something like this
$arr = array(
array(
'id' => 1,
'other_data' => 'ganesh'
),
array(
'id' => 2,
'other_data' => 'ramesh'
),
array(
'id' => 3,
'other_data' => '4'
)
);
$exists_flag = false;
foreach($arr as $inside_arr)
{
if($inside_arr['other_data'] == 4) {
$exists_flag = true;
break;
}
}
print($exists_flag);
Hope this helps!
As it stand, your array is wrong, you need to separate multi array with commas, you need to not that in_array() will not work with multi array, however you may create a recursive function that will check a provided key does exists or not in an array try code below, hope it helps ,
<?php
$arr = array(
array(
'id' => 1,
'other_data' => 'ganesh'
),
array(
'id' => 2,
'other_data' => 'ramesh'
),
array(
'id' => 3,
'other_data' => '4'
)
);
function search_items($search_value, $array)
{
foreach ($array as $item) {
if (($item == $search_value) || (is_array($item) && search_items($search_value, $item))) {
return true;
}
}
return false;
}
echo search_items("4", $arr) ? 'item found' : 'item not found';
?>
$result = array_search(4, array_column($arr, 'id'));
If we split this into steps then it would be the following:
$allColumnsNamedId = array_column($arr, 'id'); // find all columns with key 'id'
$resultBoolean = array_search(4, $allColumnsNamedId); //search the array for value 4
if($resultBoolean) {
echo 'Exists';
} else {
echo 'Does not exist';
}
Well, I am here again dealing with arrays in php. I need your hand to guide me in the right direction. Suppose the following array:
-fruits
--green
---limon
---mango
--red
---apple
-cars
--ferrari
---enzo
----blue
----black
---318
--lamborg
---spider
---gallardo
----gallado-96
-----blue
-----red
-----gallado-98
The - (hyphen) symbol only illustrates the deep level.
Well, I need to build another array (or whatever), because it should be printed as an HTML select as below:
-fruits
--green
---limon
---mango
--red
---apple
-cars
--ferrari
---enzo
----blue
----black
---318
--lamborg
---spider
---gallardo
----gallado-96
-----blue
-----red
-----gallado-98
Looks that for each level element, it should add a space, or hyphen to determinate that it belongs to a particular parent.
EDIT
The have provide an answer provideng my final code. The html select element will display each level as string (repeating the "-" at the begging of the text instead multi-level elements.
Here's a simple recursive function to build a select dropdown given an array. Unfortunately I'm not able to test it, but let me know if it works. Usage would be as follows:
function generateDropdown($array, $level = 1)
{
if ($level == 1)
{
$menu = '<select>';
}
foreach ($array as $a)
{
if (is_array($a))
{
$menu .= generateDropdown($a, $level+1);
}
else
{
$menu .= '<option>'.str_pad('',$level,'-').$a.'</option>'."\n";
}
}
if ($level == 1)
{
$menu = '</select>';
}
return $menu;
}
OK, I got it with the help of #jmgardhn2.
The data
This is my array:
$temp = array(
array(
'name' => 'fruits',
'sons' => array(
array(
'name' => 'green',
'sons' => array(
array(
'name' => 'mango'
),
array(
'name' => 'banana',
)
)
)
)
),
array(
'name' => 'cars',
'sons' => array(
array(
'name' => 'italy',
'sons' => array(
array(
'name' => 'ferrari',
'sons' => array(
array(
'name' => 'red'
),
array(
'name' => 'black'
),
)
),
array(
'name' => 'fiat',
)
)
),
array(
'name' => 'germany',
'sons' => array(
array(
'name' => 'bmw',
)
)
),
)
)
);
Recursive function
Now, the following function will provide an array with items like [level] => [name]:
function createSelect($tree, $items, $level)
{
foreach ($tree as $key)
{
if (is_array($key))
{
$items = createSelect($key, $items, $level + 1);
}
else
{
$items[] = array('level' => $level, 'text' => $key);
}
}
return $items;
}
Calling the funcion
Now, call the function as below:
$items = createSelect($temp, array(), 0);
Output
If you iterate the final $items array it will look like:
1fruits
2green
3mango
3banana
1cars
2italy
3ferrari
4red
4black
3fiat
2germany
3bmw
$array = array(
array(
'id' => 1,
'name' => 'John Doe',
'upline' => 0
),
array(
'id' => 2,
'name' => 'Jerry Maxwell',
'upline' => 1
),
array(
'id' => 3,
'name' => 'Roseann Solano',
'upline' => 1
),
array(
'id' => 4,
'name' => 'Joshua Doe',
'upline' => 1
),
array(
'id' => 5,
'name' => 'Ford Maxwell',
'upline' => 1
),
array(
'id' => 6,
'name' => 'Ryan Solano',
'upline' => 1
),
array(
'id' =>7,
'name' => 'John Mayer',
'upline' => 3
),
);
I want to make a function like:
function get_downline($userid,$users_array){
}
Then i want to return an array of all the user's upline key with the value as $userid. I hope anyone can help. Please please...
You could do it with a simple loop, but let's use this opportunity to demonstrate PHP 5.3 anonymous functions:
function get_downline($id, array $array) {
return array_filter($array, function ($i) use ($id) { return $i['upline'] == $id; });
}
BTW, I have no idea if this is what you want, since your question isn't very clear.
If you need do search thru yours array by $id:
foreach($array as $value)
{
$user_id = $value["id"];
$userName = $value["name"];
$some_key++;
$users_array[$user_id] = array("name" => $userName, "upline" => '1');
}
function get_downline($user_id, $users_array){
foreach($users_array as $key => $value)
{
if($key == $user_id)
{
echo $value["name"];
...do something else.....
}
}
}
or to search by 'upline':
function get_downline($search_upline, $users_array){
foreach($users_array as $key => $value)
{
$user_upline = $value["upline"];
if($user_upline == $search_upline)
{
echo $value["name"];
...do something else.....
}
}
}
Code :
function get_downline($userid,$users_array)
{
$result = array();
foreach ($users_array as $user)
{
if ($user['id']==$userid)
$result[] = $user['upline'];
}
return result;
}
?>
Example Usage :
get_downline(4,$array);