【问题标题】:Keeping only first 10 records in a specific subarray在特定子数组中仅保留前 10 条记录
【发布时间】:2019-12-10 02:54:49
【问题描述】:

我有一些 JSON 格式如下:

{
  "mainKey": [
    {
      "ID": "1018",
      "dish": "Fish",
      "desert": "Ice cream",
      "drink": "Cola"
    },
    {
      "ID": "1019",
      "dish": "Pizza",
      "desert": "Cake",
      "drink": "Water"
    },
    ...
  ],
  "anotherKey": [
    {
      "something": "something",
      "something": 123,
      "something": 123
    },
    ...
  ],
  ...
}

有很多键和很多数据,我将其缩短以显示基本结构。此 JSON 位于名为 $response 的变量中。我首先将其转换为数组:

$response = json_decode($response, true);

unset 需要几个键,所以我只需循环数组并取消设置它们:

foreach ($response as $key => $value) {
    if($key === 'mainKey') {

    }
    unset($response['another_key']);
    unset($response['yet_another_key']);
}

我并没有取消所有键,只是几个键。我现在要做的是在 mainKey 上工作,这就是为什么我在循环中包含一个 if 语句。

如何只保留来自mainKey 的前 10 条记录?我见过像splice 这样的东西,但这会保留我数组中的其他键吗?这是否也会保留我的索引,因为这些索引对我很重要?

考虑到mainKey 拥有超过 10 万条记录,最有效的方法是什么?

【问题讨论】:

  • 在 foreach 外创建一个计数器 $i = 1;,然后在 foreach 内创建一个表达式 if($i++ >= 10)
  • foreach(array_slice($response['mainkey'],0,10) as $val) { // 做人员} unset($response;'mainkey'); foreach($response as $val ) { // 做其他的 }
  • 如果你只想和mainkey合作,你可以简单$data = $response['mainKey'];

标签: php multidimensional-array filtering


【解决方案1】:

不需要循环;函数可以以非常干净简洁的方式完成这项工作。

代码:(Demo)

$black_keys = array_flip(['another_key', 'yet_another_key']);    // blacklist

$array = array_diff_key(json_decode($json, true), $black_keys);  // decode and filter
$array['mainKey'] = array_slice($array['mainKey'], 0, 10);       // truncate mainKey subarray

var_export($array);

或者,这会稍微好一点:

$array = json_decode($json, true);
unset($array['another_key'], $array['yet_another_key']);
$array['mainKey'] = array_slice($array['mainKey'], 0, 10);

【讨论】:

    【解决方案2】:

    由于mainKey 将具有基于数字的键,因此您可以创建一个过滤器来删除所有超出给定范围的项目。

    <?php
    
    $json = '{
      "mainKey": [
        {
          "ID": "1018",
          "dish": "Fish",
          "desert": "Ice cream",
          "drink": "Cola"
        },
        {
          "ID": "1019",
          "dish": "Pizza",
          "desert": "Cake",
          "drink": "Water"
        }
      ],
      "anotherKey": [
        {
          "ID": "something",
          "dish": "123",
          "desert": "123"
        }
      ]
    }';
    
    $response = json_decode($json, true);
    
    // If needed, unset your keys 
    unset($response['anotherKey']);    
    ...
    
    // Now, let's work only with `mainKey`
    $mainKey = $response['mainKey'];
    
    // Create a range of keys to keep
    $allowed  = range(0, 10);
    
    // Finally, filter out all keys not in the range you specified.
    $filtered = array_filter(
        $mainKey,
        function ($key) use ($allowed) {
            return in_array($key, $allowed);
        },
        ARRAY_FILTER_USE_KEY
    );
    
    // `$filtered` now only has keys 0-10. 
    var_dump($filtered);
    

    【讨论】:

    • 我认为这非常接近。它从 mainkey 获取前 10 个元素。它没有做的一件事是保留我的其他钥匙。所以说我想保留 anotherKey 而不是取消它,我可以把它和过滤数组放在一起吗?
    • 当然-不要unset($response['anotherKey']);,然后您可以在需要时检索它:$anotherKeyData = $reponse['anotherKey'];
    • $filtered 过程过于复杂。使用array_filter()range()in_array() 是一种很简单的方法。我不推荐这个答案。看我的演示。
    • 很公平。很好的解决方案。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多