I have two arrays and I need to verify what is different between them, like:
Something exists in array A but not in B,
One argument is diferent in array A when comparing to B...
$temp = import_temp::select('cod_disciplina', 'cod_turma', 'hr_inicio', 'hr_fim', 'dia_semana')->get();
$turmas;
foreach($temp as $t)
{
$turmas = Horario::select('cod_disciplina', 'cod_turma', 'hr_inicio', 'hr_fim', 'dia_semana')
->whereIn('cod_disciplina', $temp->lists('cod_disciplina'))
->whereIn('cod_turma', $temp->lists('cod_turma'))
->where('ano_semestre', $ano_semestre)->get();
}
When I do:
print_r($turmas->toArray());
print_r($temp->toArray());
I get:
How may I compare these keys and identify when something changed is new or is missing.
Tried working with array_diff_assoc but I get the following error:
Array to string conversion
array_diff_assoc($temp->toArray(), $turmas->toArray());
Also tried This that I found in another answer in a similar question but didn't work.
First define your own function to compare arrays:
function arrayCmp($a, $b) {
if ($a < $b) {
return -1;
} elseif ($a > $b) {
return 1;
} else {
return 0;
}
}
Then if you want elements that are present in $a bot not in $b then you call:
$diff = array_udiff($a, $b, 'arrayCmp');
Related
I have an array that carries a definite number of dimensions so I'm not really looking at something recursive (Unless maybe for maintainability sake in the future). It's a numeric array gotten from the database with each row holding another array. Each of those level 2 arrays contain strings like
var1, var2 , var3
And so on. Note the irregular appearance of commas in the string. So I intend to break the comma delimited string in the third level then log them in the final array but I get an error saying I am supplying an null array. So I want to know why it says the array is null and how I can make it recognise that as a valid array. My code goes below:
function fetch_each($arr) {
$temp = array();
for ($i = 0; $i < count($arr); $i++) {
for ($j = 0; $j < count($arr[$i]); $j++) {
array_reduce(preg_split("/[\s,]+/", $arr[$i][$j]), function($a, $b) {
return array_push($temp, $a, $b);
});
}
}
return $temp;
}
PS: Please don't mark as duplicate. I don't want to copy someone else's code but want to understand why this does not work. Thanks.
You have this problem because $temp is not visible in the function block.
To solve that, you must use the keyword use (variable_name) next to the function definition as in this example :
array_reduce(preg_split("/[\s,]+/", $arr[$i][$j]), function($a, $b) use (&$temp) {
return array_push($temp, $a, $b);
});
Just a remark, $a will contain the result of array_push
Returns:int the new number of elements in the array.
So you can remove it from the array_push() instruction to keep a clean array with only splitted strings
This question already has answers here:
Sort multidimensional array by multiple columns
(8 answers)
Closed 5 months ago.
i need one help.i am sorting array using the key value,i need if one key value will same then it should come in alphabetically order again.Let me to explain my code below.
{"data":[
{"subcat_id":"9","subcat_name":"SUSHI","order":"9"},
{"subcat_id":"20","subcat_name":"APPETIZERS","order":"6"},
{"subcat_id":"6","subcat_name":"CHINESE","order":"4"},
{"subcat_id":"26","subcat_name":"BRUNCH","order":"4"},
{"subcat_id":"17","subcat_name":"ENTREES","order":"3"},
{"subcat_id":"25","subcat_name":"HAPPY HOUR","order":"2"}
]}
here if order value will same (lets say-order->4),then it should come the alphabetically as per subcat_name(BRUNCH,CHINESE) like this.
You must create groups by order id and then sort them.
$json = '{"data":[
{"subcat_id":"9","subcat_name":"SUSHI","order":"9"},
{"subcat_id":"20","subcat_name":"APPETIZERS","order":"6"},
{"subcat_id":"6","subcat_name":"CHINESE","order":"4"},
{"subcat_id":"26","subcat_name":"BRUNCH","order":"4"},
{"subcat_id":"17","subcat_name":"ENTREES","order":"3"},
{"subcat_id":"25","subcat_name":"HAPPY HOUR","order":"2"}
]}';
$data = json_decode($json);
$ordersGroups = array();
foreach ($data->data as $orderData) {
if (!isset($ordersGroups[$orderData->order])) {
$ordersGroups[$orderData->order] = array($orderData);
} else {
$ordersGroups[$orderData->order][] = $orderData;
}
}
$ordersGroups = array_map(function ($orders) {
usort($orders, function ($a, $b) {
return strcmp($a->subcat_name, $b->subcat_name);
});
return $orders;
}, $ordersGroups);
$data->data = array_reduce($ordersGroups, function ($carry, $orderGroup) {
return array_merge($carry, $orderGroup);
}, array());
$json = json_encode($data);
This may work:
$array = //decode your JSON as an array here
$innerComparison = function ($v1, $v2) {
return strcmp($v1["subcat_name"],$v2["subcat_name"]);
};
$mainComparison = function ($v1, $v2) use ($innerComparison) {
if ($v1["order"] === $v2["order"]) {
return $innerComparison($v1,$v2);
} else {
return $v1["order"] < $v2["order"]:-1:1;
}
};
usort($array["data"], $mainComparison);
You can use usort(). Assuming your data is stored in the $obj object:
usort
(
$obj->data,
function( $a, $b )
{
if( $a->order == $b->order ) return strcmp( $a->subcat_name, $b->subcat_name );
return $a->order - $b->order;
}
);
above function sort $obj->data according to your request.
eval.in demo
usort() sort an array using a custom function, that receive two elements of array as arguments: the returned function value must be an integer less than, equal to, or greater than zero if the first argument is considered to be respectively less than, equal to, or greater than the second.
In your case, if ->order keys are equals, we use strcmp() to return sort value based on ->subcat_name, otherwise we return the difference between two ->order values.
Read more about usort()
Read more about strcmp()
I’m working on a little PHP function that will sort an array based off of if the item returned isVerified or not. If it is in fact verified, I'd like those results to be displayed at the top of the list. I admit I’m not the most familiar with PHP and I’ve been doing a lot of reading up since I figured there could possibly be a method to make this easier. Reading around it sounded like the uasort() was what I needed for its sorting abilities and that it maintains index association, but I’m a little confused as how to properly use it. The original block of PHP I am working on looks like this:
<?php
if (count($results)):
$lexisIndex = 1;
foreach ($results as $person){
$person->isVerified = (substr($person->first_name, 0, 1) == substr($fname, 0, 1) && $person->last_name == $lname );
$person->lexisIndex = $lexisIndex++;
}
foreach ($results as $person):
?>
From here I put the $results into an array and passed it into a uasort function. After I added what I thought I needed the code looked like this:
<?php
if (count($results)):
$lexisIndex = 1;
foreach ($results as $person){
$person->isVerified = (substr($person->first_name, 0, 1) == substr($fname, 0, 1) && $person->last_name == $lname );
$person->lexisIndex = $lexisIndex++;
}
$array = array($results);
uasort($array, function($a, $b) {
if ($a == $b) {
return 0;
}
return ($a < $b ? -1 : 1);
});
foreach ($results as $person):
?>
This still didn't work for me and didn't throw any errors so I'm having a heck of a time trying to work this one out. Am I on the right track with what I'm using? Or can this be done in a more efficient manner? I apologize if this is sounds like a question that has been asked before, but I couldn't find a fix while searching around. If this is a duplicate I'm more than happy to click a link and do some more reading. Thanks for your time and help.
$a and $b are the elements of the array. So in your case, they are person objects, and that's how you should compare them:
uasort($array, function($a, $b) {
// isVerified is most important. Move to top.
if ($a->isVerified != $b->isVerified ) {
return ($a->verified ? -1 : 1);
}
// If neither or both are verified, compare based on lexisindex.
return $a->lexisIndex - $b->lexisIndex;
});
The last line is just a shortcut. A comparison function doesn't need to return -1, 0 or 1. It just accepts any value < 0 to indicate that $a is 'smaller' than $b, 0 for equality or > 0 for larger. So your current compare callback, which would compare numeric values, could also just be written as return $a - $b;. You could also write the last line like this, but it's not necessary:
return ($a->lexisIndex < $b->lexisIndex ? -1 : 1);
I have original array like this:
$arr=array(10,8,13,8,5,10,10,12);
and want to sort so finally become:
$arr=array(10,10,10,8,8,13,12,5);
To get final result i using this way:
$arr=array(10,8,13,8,5,10,10,12);
// Remove array that contain array(1)
$arr_diff=array_diff(array_count_values($arr), array(1));
// Remove array that contain keys of $arr_diff
$arr=array_diff($arr, array_keys($arr_diff));
// Sort
rsort($arr);
ksort($arr_diff);
// unshift
foreach ($arr_diff as $k=>$v)
{
while ($v > 0)
{
array_unshift($arr,$k);
$v--;
}
}
// print_r($arr);
My question is there an another more simple way?
Thanks.
$occurrences = array_count_values($arr);
usort($arr, function ($a, $b) use ($occurrences) {
// if the occurrence is equal (== 0), return value difference instead
return ($occurrences[$b] - $occurrences[$a]) ?: ($b - $a);
});
See Reference: all basic ways to sort arrays and data in PHP.
This code does not run properly, but it suggests what I am trying to do:
function sort_2d_by_index($a,$i) {
function cmp($x, $y) {
// Nested function, can't find $i
// (global $i defeats the purpose of passing an arg)
if ($x[$i] == $y[$i]) { return 0; }
return ($x[$i] < $y[$i]) ? -1 : 1;
}
usort($a,"cmp");
return $a;
}
There HAS to be a much better way to do this. I've been examining ksort(), multisort(), and all sorts of sorts until I'm sort of tired trying to sort it all out.
The situation is this: I've got a 2-d array...
array(
array(3,5,7),
array(2,6,8),
array(1,4,9)
);
...and I want to sort by a column index. Say, column [1], would give this result:
array(
array(1,4,9),
array(3,5,7),
array(2,6,8)
);
Does someone have a link (I'm sure this has been asked before), or could someone say "you need foosort, definitely". Thanks very much.
In the documentation of array_multisort it is mentioned that it can be used for this kind of thing.
You can't avoid creating an array that consists of only one column:
$sort_column = array();
foreach ($a as $row)
$sort_column []= $row[1]; // 1 = your example
array_multisort($sort_column, $a);
This sorts both arrays synchronously so that afterwards your whole array is sorted in the same order as the $sort_column array is.
As of PHP 5.3 you can use a closure (pass $i into the function) by defining your cmp function like this:
$cmp = function($x, $y) use ($i) { ... };
You can use use to access $i:
function cmp($x, $y) use ($i) {
// $i now available
if ($x[$i] == $y[$i]) { return 0; }
return ($x[$i] < $y[$i]) ? -1 : 1;
}
http://www.php.net/manual/en/function.sort.php#99419
phpdotnet at m4tt dot co dot uk
Simple function to sort an array by a specific key. Maintains index association.