Reputation: 10621
I have a multidimensional array that is from a JSON API:
{
"status": "success",
"data": [
{
"id": 7,
"anchor": "Atkins Diet Coupon",
"status": "viewed",
"points": 0,
"latest_date": 1432135046,
"created_date": 1432134221,
"contacted": true
},
{
"id": 6,
"anchor": "Videostripe",
"status": "viewed",
"points": 0,
"latest_date": 1432134545,
"created_date": 1432131231,
"contacted": false
},
{
"id": 1,
"anchor": "Smilebox",
"status": "viewed",
"points": 0,
"latest_date": 1432053140,
"created_date": 1432131131,
"contacted": false
}
]
}
I convert it using the following PHP code:
$data = file_get_contents($api_url);
$data = json_decode($data, true);
I have a list of ids that I want to have displayed first in the multidimensional array:
$ids = array('1','6');
So in this example: the multidimensional array would be reordered with 1,6,7 based on the order of the ids array, and then reverting back to its original order if not featured in the ids array.
This is a very complicated thing and I'm not sure at all how to do it!
Upvotes: 0
Views: 97
Reputation: 3582
This I believe is a cleaner code :)
$ids = [1,6];
sort($ids); // Optional (For cases where you mistakenly write [1,7,6])
usort($data, function($a, $b) {
return $a['id'] > $b['id'];
});
$ordered = array_filter($data, function($arrayData) use ($ids) {
return (in_array($arrayData['id'], $ids));
});
$unordered = array_filter($data, function($arrayData) use ($ids) {
return (!in_array($arrayData['id'], $ids));
});
$finalArray = array_merge($ordered, $unordered);
Glad to help :)
Upvotes: 1
Reputation: 3792
You can map the data to the ids. Then loop over $ids
and grab the corresponded data in order of id appearance in the array, also unset founded $data
elements. Then append the elements left in the $data
to the end of the array containing founded elements.
$data = array_combine(
array_column($response['data'], 'id'),
$response['data']
);
$keyed = array_map(function ($id) use (&$data) {
if (isset($data[$id])) {
$datum = $data[$id];
unset($data[$id]);
return $datum;
}
return null;
}, $ids);
$data = array_values($keyed + $data);
Here is demo.
Note that when there's no element with te given id
the null
values will be placed.
Upvotes: 0
Reputation: 21502
$result = [];
// Convert the values into keys for convenience.
// It is easy to check if ID exists with isset($keys[$id]).
$keys = array_flip($ids);
// Collect items $ids
foreach ($ids as $id) {
// Search for an item with this ID
foreach ($data['data'] as $item) {
if ($item['id'] == $id) {
$result []= $item;
break;
}
}
}
// Collect the rest of the items
foreach ($data['data'] as $item) {
if (!isset($keys[$item['id']]))
$result []= $item;
}
Upvotes: 0
Reputation: 2642
You can create another array with first values from your ID array and then other elements. You can create a custom function to get the key of the element from the array associated with the value of ID . Below code may help you. This is not fixed for (1,6). This is general solution. You can put any order, any number of elements.
<?php
$data = '{
"status": "success",
"data": [
{
"id": 7,
"anchor": "Atkins Diet Coupon",
"status": "viewed",
"points": 0,
"latest_date": 1432135046,
"created_date": 1432134221,
"contacted": true
},
{
"id": 6,
"anchor": "Videostripe",
"status": "viewed",
"points": 0,
"latest_date": 1432134545,
"created_date": 1432131231,
"contacted": false
},
{
"id": 1,
"anchor": "Smilebox",
"status": "viewed",
"points": 0,
"latest_date": 1432053140,
"created_date": 1432131131,
"contacted": false
}
]
}';
Convert to array, create ids array,initialize a reorder array
$data = json_decode($data, true);
$ids= array(1,6);
$array_elements = $data['data'];
$reordered_array=array();
Use foreach to fill the re-ordered array with the ids from the array.Use custom function to find the element. Remove the moved elements from the array. then merge them together.
foreach($ids as $id)
{
$get_key = mycustfunction($array_elements,'id',$id);
$reordered_array[] = $array_elements[$get_key];
unset($array_elements[$get_key]);
}
$result_array = array_merge($reordered_array,$array_elements);
print_r($result_array);
Custom function
function mycustfunction($products, $field, $value)
{
foreach($products as $key => $product)
{
if ( $product[$field] === $value )
return $key;
}
return false;
}
Upvotes: 0
Reputation: 7385
You can use usort
to specify your own rules for sorting.
For example:
$ids = array('1','6');
usort($data["data"], function ($a, $b) use ($ids) {
$pos_a = array_search($a['id'], $ids);
$pos_b = array_search($b['id'], $ids);
if ($pos_a === FALSE && $pos_b === FALSE) {
return $a['id'] - $b['id'];
}
if ($pos_a === FALSE) {
return 1;
}
if ($pos_b === FALSE) {
return -1;
}
return $pos_a - $pos_b;
});
var_dump($data);
Upvotes: 1