PHP: Sort multidimensional array, but keep its substructure - php

I have a multidimensional arrays with the following structure:
$arr[0][0] = 1.24;
$arr[0][1] = 5.21;
$arr[0][2] = 2.72;
$arr[0][3] = 1.89;
$arr[0][4] = 4.62;
$arr[1][0] = 3.45;
$arr[1][1] = 5.61;
$arr[1][2] = 2.62;
$arr[1][3] = 1.12;
$arr[1][4] = 1.35;
This array should get sorted while keeping the suborder of $arr[0] and $arr[1], so the result looks like this:
$arr[0][0] = 1.24;
$arr[1][0] = 3.45;
$arr[0][1] = 5.21;
$arr[0][2] = 2.72;
$arr[0][3] = 1.89;
$arr[0][4] = 4.62;
$arr[1][2] = 2.62;
$arr[1][3] = 1.12;
$arr[1][4] = 1.35;
$arr[1][1] = 5.61;
I do not care in which form the result get saved, but I need both keys and the value. Hope you understand and can help me.

How about looping the outer array and sorting the inner?
foreach ($arr as $id => $data) {
sort($data);
$arr[$id] = $data;
}

$arr[0][0] = 1.24;
$arr[0][1] = 5.21;
$arr[0][2] = 2.72;
$arr[0][3] = 1.89;
$arr[0][4] = 4.62;
$arr[1][0] = 3.45;
$arr[1][1] = 5.61;
$arr[1][2] = 2.62;
$arr[1][3] = 1.12;
$arr[1][4] = 1.35;
$size = count($arr);
$outArr= array();
foreach($arr[0] as $key =>$value)
{
$resArr = array();
for($i = 0 ; $i< $size ; $i++)
{
$resArr[] = $arr[$i][$key] ;
}
sort($resArr);
$outArr[$key] = $resArr;
}
echo "<pre>";
print_r($outArr);
Check if this is a closer solution.

Related

$array[$key] = $something creates a new array

I have this php code that's supposed to check how many times a single item is in an array and put the amount in the value of that key.
im asking, why does the $duplicates[$item] += 1; create a new array instead of appending it to the existing array
here is the picture of the output I get.
this is my code:
$itemQuery = $con->prepare("SELECT cart_value FROM active_carts WHERE username=:prodName");
$itemQuery->bindParam(":prodName" , $uname , PDO::PARAM_STR);
$itemQuery->execute();
$itemCount = $itemQuery->fetchAll();
$arrax = $itemCount[0]["cart_value"];
$itemArrX = explode(",", $arrax);
$inQuestion = array();
$duplicates = array();
foreach ($itemArrX as $item) {
if (in_array($item , $inQuestion)) {
$counter = 0;
if (!array_key_exists($item , $duplicates)) {
$duplicates[$item] = $counter;
// doesnt even execute
} else {
echo $duplicates[$item]; // echoes a new array every time
$duplicates[$item] += 1;
}
} else {
array_push($inQuestion, $item);
}
}
It is rather simple, you never created that item in the array.
$data[$key] = $value; //examine that.
try this $duplicates[$item] = $item;
then $duplicates[$item] += 1;
If you're just looking for a count of duplicate values, I like the suggestion about array_count_values() in the comments. That can be run through array_filter() to remove the non-duplicate values.
$itemQuery = $con->prepare("SELECT cart_value FROM active_carts WHERE username=:prodName");
$itemQuery->execute([":prodName"=>$uname]);
$itemArrX = explode(",", $itemQuery->fetchColumn(0));
$itemArrX = ["foo","bar","baz","bar","boo","baz"];
$duplicates = array_filter(array_count_values($itemArrX), function($v){return $v>1;});
$inQuestion = array_unique($itemArrX);
print_r($duplicates);
print_r($inQuestion);
Or here's a condensed version of your code which should work just fine.
$itemQuery = $con->prepare("SELECT cart_value FROM active_carts WHERE username=:prodName");
$itemQuery->execute([":prodName"=>$uname]);
$itemArrX = explode(",", $itemQuery->fetchColumn(0));
$itemArrX = ["foo","bar","baz","bar","boo","baz"];
$duplicates = [];
$inQuestion = [];
foreach ($itemArrX as $item) {
if (in_array($item, $inQuestion)) {
echo $duplicates[$item];
$duplicates[$item]++;
} else {
$duplicates[$item] = 1;
$inQuestion[] = $item;
}
}
print_r($duplicates);
print_r($inQuestion);

array_multisort how to mount with foreach

I need to mount an array_multisort with the values from one array.
I tryied to mount a string concated and call on the array_multidimensional like here:
function ordenar_matriz_ultima_posicion_por_distancia($matriz_up,$m_vehiculo_distancias){
$total_vehiculos=count($matriz_up[id_vehiculo]);
//resetear las keys de vehiculos para coger bien los kms y asignarlos
$a_vehiculo_distancia = array_values($m_vehiculo_distancias);
$ordenar = array();
foreach ($a_vehiculo_distancia as $key) {
$ordenar[] = $key;
}
sort($m_vehiculo_distancias);
$string= "";
$ultim_key = end(array_keys($matriz_up));
foreach ($matriz_up as $key => $valor) {
if ($key != $ultim_key) $string.= $matriz_up[$key].',';
else $string.= $matriz_up[$key];
$aaa = '$matriz_up[$key]';
}
echo $string;
echo "<br>";
array_multisort($ordenar, SORT_ASC, $string);
for($i=0;$i<$total_vehiculos;$i++){
$matriz_up['cercanos'][$i] = $m_vehiculo_distancias[$i];
echo $matriz_up['id_vehiculo'][$i]."<br>";
echo $matriz_up['fecha_gps'][$i]."<br>";
echo $matriz_up['id_tipo_posicion'][$i]."<br>";
echo $matriz_up['cercanos'][$i]."<br>";
echo $matriz_up['vaina'][$i]."<br>";
echo "------------<br>";
}
return $matriz_up;
}
$matriz_up['id_vehiculo'][0] = 9;
$matriz_up['fecha_gps'][0] = '2014';
$matriz_up['id_tipo_posicion'][0] = 11111;
$matriz_up['cercanos'][0] = 0;
$matriz_up['vaina'][0] = 12345;
$matriz_up['id_vehiculo'][1] = 3;
$matriz_up['fecha_gps'][1] = '2015';
$matriz_up['id_tipo_posicion'][1] = 22222;
$matriz_up['cercanos'][1] = 0;
$matriz_up['vaina'][1] = 5555;
$matriz_up['id_vehiculo'][2] = 1;
$matriz_up['fecha_gps'][2] = '2016';
$matriz_up['id_tipo_posicion'][2] = 33333;
$matriz_up['cercanos'][2] = 0;
$matriz_up['vaina'][2] = 988;
$matriz_up['id_vehiculo'][3] = 4;
$matriz_up['fecha_gps'][3] = '2017';
$matriz_up['id_tipo_posicion'][3] = 44444;
$matriz_up['cercanos'][3] = 0;
$matriz_up['vaina'][3] = 777;
$m_vehiculo_distancias[9] = 345;
$m_vehiculo_distancias[3] = 712;
$m_vehiculo_distancias[1] = 10;
$m_vehiculo_distancias[4] = 35;
ordenar_matriz_ultima_posicion_por_distancia($matriz_up,$m_vehiculo_distancias);
With this array_multisort works, but i need to take all the key without put manually..
array_multisort($ordenar, SORT_ASC, $matriz_up['id_vehiculo'], $matriz_up['fecha_gps'], $matriz_up['id_tipo_posicion'], $matriz_up['vaina'] );
Try this code:
<?php
$matriz_up = $m_vehiculo_distancias = array();
$matriz_up['id_vehiculo'][0] = 9;
$matriz_up['fecha_gps'][0] = '2014';
$matriz_up['id_tipo_posicion'][0] = 11111;
$matriz_up['cercanos'][0] = 0;
$matriz_up['vaina'][0] = 12345;
$matriz_up['id_vehiculo'][1] = 3;
$matriz_up['fecha_gps'][1] = '2015';
$matriz_up['id_tipo_posicion'][1] = 22222;
$matriz_up['cercanos'][1] = 0;
$matriz_up['vaina'][1] = 5555;
$matriz_up['id_vehiculo'][2] = 1;
$matriz_up['fecha_gps'][2] = '2016';
$matriz_up['id_tipo_posicion'][2] = 33333;
$matriz_up['cercanos'][2] = 0;
$matriz_up['vaina'][2] = 988;
$matriz_up['id_vehiculo'][3] = 4;
$matriz_up['fecha_gps'][3] = '2017';
$matriz_up['id_tipo_posicion'][3] = 44444;
$matriz_up['cercanos'][3] = 0;
$matriz_up['vaina'][3] = 777;
$m_vehiculo_distancias[9] = 345;
$m_vehiculo_distancias[3] = 712;
$m_vehiculo_distancias[1] = 10;
$m_vehiculo_distancias[4] = 35;
function sortArray($arrayToSortParam, $orderArray)
{
$result = array();
$arrayToSort = $arrayToSortParam;
$keys = array_keys($arrayToSort);
asort($orderArray, true);
$newSort = $cercanos = array();
foreach($orderArray as $key => $value)
{
$newSort[] = array_keys($arrayToSort['id_vehiculo'], $key)[0];
$cercanos[] = $orderArray[$key];
}
foreach($keys as $keyName)
{
uksort($arrayToSort[$keyName], function($key1, $key2) use ($newSort) {
return (array_search($key1, $newSort) > array_search($key2, $newSort));
});
}
$arrayToSort['cercanos'] = $cercanos;
//reset indexes
foreach($keys as $keyName)
{
$arrayToSort[$keyName] = array_values($arrayToSort[$keyName]);
}
return $arrayToSort;
}
echo '<pre>';
//print_r($matriz_up);
//print_r($m_vehiculo_distancias);
print_r(sortArray($matriz_up, $m_vehiculo_distancias)); //this is result
Working fiddle: CLICK!

Merging two arrays removing duplicate keys from one

I have two arrays. Those are below:
First Array:
$arr1[0] = 'Programs';
$arr1[1] = 'Levels';
$arr1[2] = 'Presenters';
$arr1[3] = 'Levels';
Second Array:
$arr2[0] = 'Art';
$arr2[1] = 'Primary';
$arr2[2] = 'Kristine Ballard';
$arr2[3] = 'Secondary';
I want to get output like this:
Programs = Art
Levels = Primary, Secondary
Presenters = Kristine Ballard
Can anyone help?
With the following, you would create a multidimensional array, if there are multiple values of a key:
$arr1[0] = 'Programs';
$arr1[1] = 'Levels';
$arr1[2] = 'Presenters';
$arr1[3] = 'Levels';
$arr2[0] = 'Art';
$arr2[1] = 'Primary';
$arr2[2] = 'Kristine Ballard';
$arr2[3] = 'Secondary';
$newArray = array();
foreach($arr1 as $index => $key) {
$newArray[$key][] = $arr2[$index];
}
print_r($newArray);
Output:
Array
(
[Programs] => Array
(
[0] => Art
)
[Levels] => Array
(
[0] => Primary
[1] => Secondary
)
[Presenters] => Array
(
[0] => Kristine Ballard
)
)
$arr1[0] = 'Programs';
$arr1[1] = 'Levels';
$arr1[2] = 'Presenters';
$arr1[3] = 'Levels';
$arr2[0] = 'Art';
$arr2[1] = 'Primary';
$arr2[2] = 'Kristine Ballard';
$arr2[3] = 'Secondary';
$newArray = [];
$mi = new MultipleIterator();
$mi->attachIterator(new ArrayIterator($arr1));
$mi->attachIterator(new ArrayIterator($arr2));
foreach($mi as list($key, $value)) {
$newArray[$key][] = $value;
}
var_dump($newArray);
Note that the use of foreach() with list() requires PHP>=5.5.0
For earlier versions of PHP, the following will work:
$newArray = [];
$mi = new MultipleIterator(MultipleIterator::MIT_NEED_ALL | MultipleIterator::MIT_KEYS_ASSOC);
$mi->attachIterator(new ArrayIterator($arr1), 'key');
$mi->attachIterator(new ArrayIterator($arr2), 'value');
foreach($mi as $details) {
extract($details);
$newArray[$key][] = $value;
}
var_dump($newArray);
I got another solution by myself and this is working. I have just posted it below for the help to others who will see this thread. Here is my code:
$arr1[0] = 'Programs';
$arr1[1] = 'Levels';
$arr1[2] = 'Presenters';
$arr1[3] = 'Levels';
$arr2[0] = 'Art';
$arr2[1] = 'Primary';
$arr2[2] = 'Kristine Ballard';
$arr2[3] = 'Secondary';
$new_arr1 = array_values(array_unique($arr1));
for ($i = 0; $i < count($new_arr1); $i++)
{
$var = 0;
echo $new_arr1[$i]. ': ';
for ($j = 0; $j < count($arr1); $j++)
{
if($new_arr1[$i] == $arr1[$j])
{
if($var == 0)
{
echo $arr2[$j];
}
else
{
echo ', ' . $arr2[$j];
}
$var++;
}
}
echo '<br>';
}

Remove duplicate array data using PHP

i want to remove the data from the array when there profile_id duplicate.
this is my array
$response[0]['profile_id'] = 100;
$response[0]['profile_name'] = 'deepu';
$response[0]['address'] = 'deesdvsdvsdvpu';
$response[1]['profile_id'] = 101;
$response[1]['profile_name'] = 'deepu';
$response[1]['address'] = 'deesdvsdvsdvpu';
$response[2]['profile_id'] = 100;
$response[2]['profile_name'] = 'deepu';
$response[2]['address'] = 'deesdvsdvsdvpusdvsdvsdvsdvsdv';
$response[3]['profile_id'] = 102;
$response[3]['profile_name'] = 'desdvsdvepu';
$response[3]['address'] = 'deesdvsdvsdvpusdvsdvsdvsdvsdsdvsdvv';
$input = array_map("unserialize", array_unique(array_map("serialize", $response)));
i want this output
$response[0]['profile_id'] = 100;
$response[0]['profile_name'] = 'deepu';
$response[0]['address'] = 'deesdvsdvsdvpu';
$response[1]['profile_id'] = 101;
$response[1]['profile_name'] = 'deepu';
$response[1]['address'] = 'deesdvsdvsdvpu';
$response[3]['profile_id'] = 102;
$response[3]['profile_name'] = 'desdvsdvepu';
$response[3]['address'] = 'deesdvsdvsdvpusdvsdvsdvsdvsdsdvsdvv';
But I can't get this. If anyone knows about this please help me.
Try the php-function: array_unique
Or manual:
$ids = array();
foreach($response as $key => $entry){
if(in_array($entry['profile_id'], $ids)){
unset($response[$key]);
}else{
$ids[] = $entry['profile_id'];
}
}
$new_arr = array_reduce($response, function($t, $v) {
$profile_id = $v['profile_id'];
if (!isset($t[$profile_id]))
$t[$profile_id] = $v;
return $t;
}, array());
$new_arr = array_values($new_arr); // to get indexes back to 0, 1, 2...

PHP array comparison and finding matched and non matched items

I have been using this script for finding matched and nonmatched array items.
My code is.
$filter1 = "red,green,blue,yellow";
$parts1 = explode(',', $filter1);
$filter2 = "red,green,blue";
$parts2 = explode(',', $filter2);
for($i=0; $i< count($parts1); $i++)
{
for($j=0; $j< count($parts2); $j++)
{
if($parts1[$i] == $parts2[$j])
{
$match[] = $parts1[$i];
} else {
$nomatch[] = $parts1[$i];
}
}
}
print_r($match);
echo "<br>";
print_r($nomatch);
By using this code i am only getting the matched items and not nonmatched. Can anybody help.
Thanks in advance.
You can try using array_intersect and array_diff
$filter1 = "red,green,blue,yellow";
$parts1 = explode(',', $filter1);
$filter2 = "red,green,blue";
$parts2 = explode(',', $filter2);
$match = array_intersect($parts1, $parts2);
$nomatch = array_diff($parts1, $parts2);
var_dump($match,$nomatch);
Output
array
0 => string 'red' (length=3)
1 => string 'green' (length=5)
2 => string 'blue' (length=4)
array
3 => string 'yellow' (length=6)
this can be done by array_intersect and array_diff
$filter1 = "red,green,blue,yellow";
$parts1 = explode(',', $filter1);
$filter2 = "red,green,blue";
$parts2 = explode(',', $filter2);
$result = array_intersect($parts1 , $parts2 );
print_r($result);
Live Example
and
$result = array_diff($parts1 , $parts2 );
print_r($result);
LIVE example
because your nested loop not run at yellow color time
try this
$filter1 = "red,green,blue,yellow";
$filter2 = "red,green,blue,gray";
or
for($j=0; $j<= count($parts2); $j++)
$filter1 = "red,green,blue,yellow";
$parts1 = explode(',', $filter1);
$filter2 = "red,green,blue";
$parts2 = explode(',', $filter2);
$match = array();
$nomatch = array();
foreach($parts1 as $v){
if(in_array($v,$parts2))
$match[]=$v;
else
$nomatch[]=$v;
}
try this
$filter1 = "red,green,blue,yellow";
$parts1 = explode(',', $filter1);
$filter2 = "red,green,blue";
$parts2 = explode(',', $filter2);
foreach($parts1 as $first)
{
if(in_array($first, $parts2))
{
$match[] = $first;
}
else
{
$nomatch[] = $first;
}
}
print_r($match);
echo "<br>";
print_r($nomatch);
or you can use array_diff to get non matched items
print_r(array_diff($parts1,$parts2));
and for matched items use
print_r(array_intersect($parts1,$parts2));
Try the below code
$filter1 = "red,green,blue,yellow";
$parts1 = explode(',', $filter1);
$filter2 = "red,green,blue,purple";
$parts2 = explode(',', $filter2);
$matching = array_intersect($parts1, $parts2);
$non_matching = array_diff(array_merge($parts1, $parts2), $matching);
Changing your code, which should have similar result for non-matching as array_diff($parts1, $parts2);
for($i=0; $i< count($parts1); $i++)
{
$is_matching = false;
for($j=0; $j< count($parts2); $j++)
{
if($parts1[$i] == $parts2[$j])
{
$is_matching = true;
break;
}
}
if ($is_matching) {
$match[] = $parts1[$i];
} else {
$nomatch[] = $parts1[$i];
}
}
You can find matching value using array_intersect and non matching value using array_diff.
Here you can see LIVE DEMO
/**
* #param $arr
*/
function pr($arr)
{
echo '<pre>';
print_r($arr);
echo '</pre>';
}
$filter1 = "red,green,blue,yellow";
$parts1 = explode(',', $filter1);
$filter2 = "red,green,blue";
$parts2 = explode(',', $filter2);
$match = array_intersect($parts1, $parts2);
$nomatch = array_diff($parts1, $parts2);
pr($match);
pr($nomatch);
Output Screen:
Array
(
[0] => red
[1] => green
[2] => blue
)
Array
(
[3] => yellow
)

Categories