按ID列表重新排序多维数组

时间:2016-11-14 07:48:31

标签: php arrays multidimensional-array

我有一个来自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
        }
    ]
}

我使用以下PHP代码转换它:

$data = file_get_contents($api_url);
$data = json_decode($data, true);

我有一个我希望首先在多维数组中显示的ID列表:

$ids = array('1','6');

所以在这个例子中:多维数组将根据ids数组的顺序重新排序1,6,7,如果没有在ids数组中显示,则恢复原始顺序。

这是一件非常复杂的事情,我根本不确定如何做到这一点!

5 个答案:

答案 0 :(得分:1)

您可以使用usort指定自己的排序规则。

例如:

$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);

答案 1 :(得分:1)

我相信这是一个更清洁的代码:)

$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);

很高兴帮助:)

答案 2 :(得分:0)

您可以使用ID数组中的第一个值创建另一个数组,然后创建其他元素。您可以创建自定义函数以从与ID值相关联的数组中获取元素的键。下面的代码可以帮助您。对于(1,6),这不是固定的。这是一般解决方案。您可以输入任何订单,任意数量的元素。

<?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
    }
]
}';

转换为数组,创建ids数组,初始化重排序数组

$data = json_decode($data, true);
$ids= array(1,6);
$array_elements = $data['data'];
$reordered_array=array();

使用foreach用数组中的id填充重新排序的数组。使用自定义函数查找元素。从数组中删除移动的元素。然后将它们合并在一起。

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);

自定义功能

function mycustfunction($products, $field, $value)
{
  foreach($products as $key => $product)
  {
     if ( $product[$field] === $value )
     return $key;
  }
  return false;
}

答案 3 :(得分:0)

$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;
}

答案 4 :(得分:0)

您可以将数据映射到ID。然后循环遍历$ids并按照数组中id出现的顺序获取相应的数据,同时取消设置$data元素。然后将$data中留下的元素追加到包含已创建元素的数组的末尾。

$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);

这是demo

请注意,如果没有给定id字符的元素,则会放置null值。