Sort Multidimensional Array By Searched Word - php

I need to sort a multidimensional array by a searched keyword.
My array is like below.
<?php
array(
array(
'name' => '11th-Physics',
'branch' => 'Plus One',
'college' => 'Plus One',
),
array(
'name' => 'JEE-IIT',
'branch' => 'Physics',
'college' => 'IIT College',
),
array(
'name' => 'Physics',
'branch' => 'Bsc Physics',
'college' => 'College of Chemistry',
),
array(
'name' => 'Chemical Engineering',
'branch' => 'Civil',
'college' => 'Physics Training Center',
),
array(
'name' => 'Physics Education',
'branch' => 'Mechanical',
'college' => 'TBR',
),
)
?>
I need to sort this array when search keyword is physics . And after Sorting i need the result like below.
NEEDED RESULT
<?php
array(
array(
'name' => 'Physics',
'branch' => 'Bsc Physics',
'college' => 'College of Chemistry',
),
array(
'name' => 'Physics Education',
'branch' => 'Mechanical',
'college' => 'TBR',
),
array(
'name' => '11th-Physics',
'branch' => 'Plus One',
'college' => 'Plus One',
),
array(
'name' => 'JEE-IIT',
'branch' => 'Physics',
'college' => 'IIT College',
),
array(
'name' => 'Chemical Engineering',
'branch' => 'Civil',
'college' => 'Physics Training Center',
),
)
?>
That is I need to sort the array first by the name which is exactly like the searched keyword. Then wildcard search in name. Then to the next key branch and same as above. Is there any php function to sort this array like my requirement. I have already checked asort, usort. But I didn't get result properly.

Just call this simple function I just created for your requirement, It works just fine :) change the priority order according to your need
function sortArray($array,$itemToSearch)
{
$sortedArray = array();
$priorityOrder = ['name','branch','college'];
foreach ($priorityOrder as $key)
{
foreach ($array as $i => $value)
{
if(strpos(strtolower($value[$key]), strtolower($itemToSearch)) === 0)
{
array_push($sortedArray, $value);
unset($array[$i]);
}
}
foreach ($array as $i => $value)
{
if(strpos(strtolower($value[$key]), strtolower($itemToSearch)) > 0)
{
array_push($sortedArray, $value);
unset($array[$i]);
}
}
}
return $sortedArray;
}

Here we go
So I started from the algorithm in this answer and modified it to fit your requirements. Since you have three different "priorities" to you sorting, we have to use some temporary variables to separate the elements we wish sorted.
// arrays used to separate each row based on the row where the word "Physics" is found
$searchName = array();
$searchBranch = array();
$searchCollege = array();
// arrays used later for array_multisort
$foundInName = array();
$foundInBranch = array();
$foundInCollege = array();
foreach ($var as $key => $row) {
if(strpos(strtolower($row['name']), 'physics') !== false) {
$searchName[$key] = $row['name'];
$foundInName[] = $row;
}
elseif(strpos(strtolower($row['branch']), 'physics') !== false) {
$searchBranch[$key] = $row['branch'];
$foundInBranch[] = $row;
}
elseif(strpos(strtolower($row['college']), 'physics') !== false) {
$searchCollege[$key] = $row['college'];
$foundInCollege[] = $row;
}
}
// Note: I use SORT_NATURAL here so that "11-XXXXX" comes after "2-XXXXX"
array_multisort($searchName, SORT_NATURAL, $foundInName); // sort the three arrays separately
array_multisort($searchBranch, SORT_NATURAL, $foundInBranch);
array_multisort($searchCollege, SORT_NATURAL, $foundInCollege);
$sortedArray = array_merge($foundInName, $foundInBranch, $foundInCollege);
Outputting $sortedArray using var_dump() gives something like:
array(5) {
[0]=> array(3) {
["name"]=> string(12) "11th-Physics"
["branch"]=> string(8) "Plus One"
["college"]=> string(8) "Plus One"
}
[1]=> array(3) {
["name"]=> string(7) "Physics"
["branch"]=> string(11) "Bsc Physics"
["college"]=> string(20) "College of Chemistry"
}
[2]=> array(3) {
["name"]=> string(17) "Physics Education"
["branch"]=> string(10) "Mechanical"
["college"]=> string(3) "TBR"
}
[3]=> array(3) {
["name"]=> string(7) "JEE-IIT"
["branch"]=> string(7) "Physics"
["college"]=> string(11) "IIT College"
}
[4]=> array(3) {
["name"]=> string(20) "Chemical Engineering"
["branch"]=> string(5) "Civil"
["college"]=> string(23) "Physics Training Center"
}
}
As you can see 11th-Physics comes out first. That is because the ASCII value of numbers is lower than that of letters. To fix this, modify the $search... arrays by prepending a high ASCII character before the string.
if(strpos(strtolower($row['name']), 'physics') !== false) {
// if the first character is a number, prepend an underscore
$searchName[$key] = is_numeric(substr($row['name'], 0, 1)) ? '_'.$row['name'] : $row['name'];
$foundInName[] = $row;
}
Which yields the following output:
array(5) {
[0]=> array(3) {
["name"]=> string(7) "Physics"
["branch"]=> string(11) "Bsc Physics"
["college"]=> string(20) "College of Chemistry"
}
[1]=> array(3) {
["name"]=> string(17) "Physics Education"
["branch"]=> string(10) "Mechanical"
["college"]=> string(3) "TBR"
}
[2]=> array(3) {
["name"]=> string(12) "11th-Physics"
["branch"]=> string(8) "Plus One"
["college"]=> string(8) "Plus One"
}
[3]=> array(3) {
["name"]=> string(7) "JEE-IIT"
["branch"]=> string(7) "Physics"
["college"]=> string(11) "IIT College"
}
[4]=> array(3) {
["name"]=> string(20) "Chemical Engineering"
["branch"]=> string(5) "Civil"
["college"]=> string(23) "Physics Training Center"
}
}
Try it here!

Related

dynanmo db filterexpression with multiple condition php

I am unable to retrieve the item using filterExpression using logical and or or in Dyanamodb php using aws sdk. can any any one provide the code with the correct syntax to retrieve the item satisfying both the condition.
$scan_response = $dynamodb->scan(array(
'TableName' => $tableName,
'ExpressionAttributeValues' => [
':val1' => ['S' => '20'],
':val2' => ['S' => 'ajay'],
'FilterExpression' => 'age = :val1 AND name = :val2'
]));
i am getting error that
filterExpression must be a associative array
Thanks in advance
try this
$scan_response = $dynamodb->scan(array(
'TableName' => $tableName,
'ExpressionAttributeValues' => [
':val1' => ['S' => '20'],
':val2' => ['S' => 'ajay']],
'FilterExpression' => 'age = :val1 AND name = :val2'
));
badly placed closing ] creates
array(2) {
["TableName"]=>
string(3) "..."
["ExpressionAttributeValues"]=>
array(3) {
[":val1"]=>
array(1) {
["S"]=>
string(2) "20"
}
[":val2"]=>
array(1) {
["S"]=>
string(4) "ajay"
}
["FilterExpression"]=>
string(28) "age = :val1 AND name = :val2"
}
}
instead of required
array(3) {
["TableName"]=>
string(3) "..."
["ExpressionAttributeValues"]=>
array(2) {
[":val1"]=>
array(1) {
["S"]=>
string(2) "20"
}
[":val2"]=>
array(1) {
["S"]=>
string(4) "ajay"
}
}
["FilterExpression"]=>
string(28) "age = :val1 AND name = :val2"
}

PHP Multidimensional Array with multiple array with same keys?

I've been trying multiple things and for the life of me can not get this to work. I'm beginning to think it maybe isn't possible at this point.
So I have a SOAP API I'm sending this array too. Below is the code I currently have that works, but does not send the multiple values. It just uses the last one as it overwrite the previous.
Looking at this thread, what I'm doing should work?
$my_array['sn'] = "234234232";
$my_array['arrayparams'] = array(
'Param' => array( 'Name' => 'sending_key', 'Value' => 'blah',),
'Param' => array( 'Name' => 'sending_key2', 'Value' => '2',),
);
$my_array['push'] = true;
$my_array['endsession'] = false;
returns:
array(4) {
["sn"]=>
string(12) "234234232"
["arrayparams"]=>
array(1) {
["Param"]=>
array(2) {
["Name"]=>
string(61) "sending_key2"
["Value"]=>
string(1) "2"
}
}
["push"]=>
bool(true)
["endsession"]=>
bool(false)
}
I'm just having a time getting it to send this instead:
array(4) {
["sn"]=>
string(12) "234234232"
["arrayparams"]=>
array(2) {
["Param"]=>
array(2) {
["Name"]=>
string(61) "sending_key"
["Value"]=>
string(1) "blah"
}
["Param"]=>
array(2) {
["Name"]=>
string(61) "sending_key2"
["Value"]=>
string(1) "2"
}
}
["push"]=>
bool(true)
["endsession"]=>
bool(false)
}
The 'Param' array is very strict and has to have this value, I can not change to 'Param2' to get it to work. Thanks in advanced!
can you do this?
$my_array['arrayparams'] = array(
array('Param' => array( 'Name' => 'sending_key', 'Value' => 'blah',)),
array('Param' => array( 'Name' => 'sending_key2', 'Value' => '2',)),
);
The problem is you can't have the key 'Param' set in more than one key.
You would need to define 'Param' as an actual array, instead of as multiple keys within in array.
like so...
$my_array['Param'] = [
['Name' => 'sending_key', 'Value' => 'blah'],
['Name' => 'sending_key2', 'Value' => '2']
];

How to compare two multidimensional arrays by certain keys in each?

I have two multidimensional arrays of the same structure.
Like this:
array(2) {
[0] =>
array(9) {
'id' =>
string(5) "44994"
'ersatzteil_id' =>
string(3) "120"
'lang' =>
string(6) "name2_tag2"
'title' =>
string(12) "Seitentüren"
'alias' =>
string(12) "seitentueren"
'content' =>
string(1610) "LOREM ISPUM BLALABLBL"
'on_main' =>
string(1) "0"
'disabled' =>
string(1) "1"
'short_text' =>
NULL
}
[1] =>
array(9) {
'id' =>
string(5) "44996"
'ersatzteil_id' =>
string(3) "122"
'lang' =>
string(6) "name1_tag1"
'title' =>
string(7) "Spoiler"
'alias' =>
string(7) "spoiler"
'content' =>
string(1513) "SOME OTHER RANDOM TEXT"
'on_main' =>
string(1) "0"
'disabled' =>
string(1) "0"
'short_text' =>
NULL
}
}
What I need to do is I need to compare first array with the second one.
I have to compare them by keys ersatzteil_id and content , and I find that they have same content I need to store element from first array in another new array, that wasn't existing before.
For example I need something like this, but more efficient:
if(array1[20]['ersatzteil_id'] == array2[145]['ersatzteil_id']
&& array1[20]['content'] == array2[145]['content']){
array3 = array1[20];
}
Try this code:-
$result = [];
foreach($array1 as $arr1){
foreach($array2 as $arr2){
if(($arr1['id'] == $arr2['id']) && ($arr1['ersatzteil_id'] == $arr2['ersatzteil_id'])){
$result[] = $arr1;
}
}
}
echo '<pre>'; print_r($result);

Sort an array by 'price' value

I have an array in the following format - I want to be able to sort this so the highest price is first - i've tried array_multisort() but I'm not having any luck so far.
$working[33] = array('id' => '33', 'price' => '250.00');
$working[34] = array('id' => '34', 'price' => '277.88');
Using some function to sort by price the end product should look as follows:- as the 277 price is greater than 250
$working[34] = array('id' => '34', 'price' => '277.88');
$working[33] = array('id' => '33', 'price' => '250.00');
Sorting using usort :
usort($working, function($a, $b) {
return $a['price'] < $b['price'] ? 1 : -1;
});
use below function to get your problem resolve
function multisort (&$array, $key) {
$valsort=array();
$ret=array();
reset($array);
foreach ($array as $ii => $va) {
$valsort[$ii]=$va[$key];
}
asort($valsort);
foreach ($valsort as $ii => $va) {
$ret[$ii]=$array[$ii];
}
$array=$ret;
}
multisort($multiarr,"order");
You can do it with array_multisort
Examples on the documentation.
Remove quotes OR use numeric sort.
String "24" is greater than "1834" because 2 is greater than 1.
My solution
$working[33] = array('id' => '33', 'price' => '250.00');
$working[34] = array('id' => '34', 'price' => '277.88');
$working[35] = array('id' => '35', 'price' => '1289.57');
$working[36] = array('id' => '36', 'price' => '15.42');
foreach ($working as $key => $row) {
$price[$key] = $row['price'];
}
array_multisort($price, SORT_NUMERIC, $working);
var_dump($working);
Output
array(4) {
[0]=>
array(2) {
["id"]=>
string(2) "36"
["price"]=>
string(5) "15.42"
}
[1]=>
array(2) {
["id"]=>
string(2) "33"
["price"]=>
string(6) "250.00"
}
[2]=>
array(2) {
["id"]=>
string(2) "34"
["price"]=>
string(6) "277.88"
}
[3]=>
array(2) {
["id"]=>
string(2) "35"
["price"]=>
string(7) "1289.57"
}
}
See Sorting arrays in php to solve your problem
usort($working, function ($a, $b) {
return bccomp($a['price'], $b['price'], 2);
});

Multi-dimensional array / creating a survey

I have an array like this:
$survey = array(
'Category1' => array(
'Question1' => array(
'Option1', 'Option2', 'Option3'
),
'Question2' => array(
'Option1', 'Option2', 'Option3'
)
),
'Category2' => array(
'Question1' => array(
'Option1', 'Option2', 'Option3'
),
'Question2' => array(
'Option1', 'Option2', 'Option3'
)
)
);
This array is in practice much larger. The requirement is 3 questions per page. My thought was to store which category and question I'm currently on. For example category 0, question 2. Then check to see if array_key_exists and if so, display, if not, increment and try again. As you might have guessed, categories and questions don't have keys (at least not numeric ones for me to loop through). So using an index is, as far as I know, is out of the question. How can I dynamically display 3 questions per page and automatically get the next 3 questions for the next page without knowing what the value is for category2, for example. How can I traverse/target this?
Thanks,
Ryan
The data seems fairly static so i would suggest changing the data format :)
Change the array into something like:
$survey = array(
array( 'name' = > 'Category1',
'questions' => array(
array(
'name' => 'Question1',
'opts' => array(
'Option1', 'Option2', 'Option3'
)
),
array(
'name' => 'Question2',
'opts' => array(
'Option1', 'Option2', 'Option3'
)
)
),
array( 'name' = > 'Category2',
'questions' => array(
array(
'name' => 'Question1',
'opts' => array(
'Option1', 'Option2', 'Option3'
)
),
array(
'name' => 'Question2',
'opts' => array(
'Option1', 'Option2', 'Option3'
)
)
)
);
And you can use integer indexes then. Just remember 2 number (the category index and the question index inside the category. And just increment until end of array in each case.
Php is not my strongest language so the code above might look strange to a native php programmer. However the root cause of OP's difficulties is the inability to easily create an interator type object. This is because of the fact that the key based array have a "strange" order given by their hash map nature. Change the nature and allow yourself to build an interator like object (aka an array index).
Since you're using an associative array (aka hash), there is no order to it. Each question and each category need to have the next question/category key with them. After that, see link-list algorithms.
My be array_keys() function will help you? You will iterate keys array (to get next keys).
<?php
$survey = array(
'Category1' => array(
'Question1' => array(
'Option1', 'Option2', 'Option3'
),
'Question2' => array(
'Option1', 'Option2', 'Option3'
),
'Question3' => array(
'Option1', 'Option2', 'Option3'
),
'Question4' => array(
'Option1', 'Option2', 'Option3'
)
),
'Category 2' => array(
'Question1' => array(
'Option1', 'Option2', 'Option3'
),
'Question2' => array(
'Option1', 'Option2', 'Option3'
)
),
'Category 3' => array(
'Question1' => array(
'Option1', 'Option2', 'Option3'
),
'Question2' => array(
'Option1', 'Option2', 'Option3'
),
'Question3' => array(
'Option1', 'Option2', 'Option3'
),
)
);
function fetchQuestions($survey, $page, $perPage = 3)
{
$results = Array();
$nCount = 0; $nRead = 0; $nIndex = $page * $perPage;
foreach ($survey as $CategoryName => $Questions)
{
foreach ($Questions as $Question => $Options)
{
if ($nCount >= $nIndex && $nRead < $perPage)
{
if (!isset($results[$CategoryName]))
$results[$CategoryName] = Array();
$results[$CategoryName][$Question] = $Options;
$nRead++;
}
$nCount++;
}
}
return $results;
}
echo '<html><body><pre>';
var_dump(fetchQuestions($survey,0));
var_dump(fetchQuestions($survey,1));
var_dump(fetchQuestions($survey,2));
echo '</pre></body></html>';
?>
And the output:
array(1) {
["Category1"]=>
array(3) {
["Question1"]=>
array(3) {
[0]=>
string(7) "Option1"
[1]=>
string(7) "Option2"
[2]=>
string(7) "Option3"
}
["Question2"]=>
array(3) {
[0]=>
string(7) "Option1"
[1]=>
string(7) "Option2"
[2]=>
string(7) "Option3"
}
["Question3"]=>
array(3) {
[0]=>
string(7) "Option1"
[1]=>
string(7) "Option2"
[2]=>
string(7) "Option3"
}
}
}
array(2) {
["Category1"]=>
array(1) {
["Question4"]=>
array(3) {
[0]=>
string(7) "Option1"
[1]=>
string(7) "Option2"
[2]=>
string(7) "Option3"
}
}
["Category 2"]=>
array(2) {
["Question1"]=>
array(3) {
[0]=>
string(7) "Option1"
[1]=>
string(7) "Option2"
[2]=>
string(7) "Option3"
}
["Question2"]=>
array(3) {
[0]=>
string(7) "Option1"
[1]=>
string(7) "Option2"
[2]=>
string(7) "Option3"
}
}
}
array(1) {
["Category 3"]=>
array(3) {
["Question1"]=>
array(3) {
[0]=>
string(7) "Option1"
[1]=>
string(7) "Option2"
[2]=>
string(7) "Option3"
}
["Question2"]=>
array(3) {
[0]=>
string(7) "Option1"
[1]=>
string(7) "Option2"
[2]=>
string(7) "Option3"
}
["Question3"]=>
array(3) {
[0]=>
string(7) "Option1"
[1]=>
string(7) "Option2"
[2]=>
string(7) "Option3"
}
}
}
There's my bid. Returns an array similar to your original array with the questions that should be displayed on that specific page.
If you want a more visual representation:
echo '<html><body>';
$page = 0;
while (count($matches = fetchQuestions($survey,$page++)) > 0)
{
echo '<div style="background-color:#CCC;">';
echo '<h2>Page '.$page.'</h2>';
echo '<ul>';
foreach ($matches as $Category => $Questions)
{
echo '<li><strong>'.$Category.'</strong>:<ul>';
foreach ($Questions as $Question => $Options)
{
echo '<li><u>'.$Question.'</u><ul>';
foreach ($Options as $Option)
echo '<li>'.$Option.'</li>';
echo '</ul>';
}
echo '</ul></li>';
}
echo '</ul>';
echo '</div>';
}
echo '</body></html>';

Categories