【问题标题】:Custom format array using foreach loop - PHP使用 foreach 循环的自定义格式数组 - PHP
【发布时间】:2021-09-13 16:26:01
【问题描述】:

我正在尝试格式化一个数组,如果它没有特定的 id,我会尝试将数据分配为 0。但它没有发生。

我面临的问题是,当我尝试添加 $dataset[$label['id']]['data'][] = 0 时,如果它是空的或在主数组 $array 的标签对象中找不到它,它就不起作用。

我有以下数组:

$array = '[{
        "id": 26,
        "name": "Tactical",
        "count": 127,
        "labels": {
            "2": {
                "id": 2,
                "risk": "Medium",
                "count": 80
            },
            "1": {
                "id": 1,
                "risk": "Low",
                "count": 39
            },
            "3": {
                "id": 3,
                "risk": "High",
                "count": 8
            }
        }
    },
    {
        "id": 14,
        "name": "Citizen Safety",
        "count": 116,
        "labels": {
            "4": {
                "id": 4,
                "risk": "Extreme",
                "count": 7
            },
            "2": {
                "id": 2,
                "risk": "Medium",
                "count": 103
            },
            "3": {
                "id": 3,
                "risk": "High",
                "count": 6
            }
        }
    },
    {
        "id": 25,
        "name": "Strategic",
        "count": 79,
        "labels": {
            "2": {
                "id": 2,
                "risk": "Medium",
                "count": 40
            },
            "1": {
                "id": 1,
                "risk": "Low",
                "count": 11
            },
            "3": {
                "id": 3,
                "risk": "High",
                "count": 28
            }
        }
    }
]';

这里是我正在尝试的代码的 sn-p

$labels = [];
$dataset = [];
    
foreach ($array as $key => $value) {
    $labels[] = $value['name'];
    foreach ($value['labels'] as $label) {
        if (empty($dataset[$label['id']])) {
            $dataset[$label['id']] = [
                'label' => $label['risk'],
                'backgroundColor' => '#FF9534'
            ];
            $dataset[$label['id']]['data'] = [];
            $dataset[$label['id']]['data'][] = $label['count'];
        } else {
            if (empty($dataset[$label['id']]['data'])) {
                $dataset[$label['id']]['data'][] = 0;
            } else {
                $dataset[$label['id']]['data'][] = $label['count'];
            }
        }
    }
}
    
$dataset = [
    'labels' => $labels,
    'datasets' => $dataset,
];
    
echo json_encode($dataset);
die;

我得到以下输出

{
    "labels": [
        "Tactical",
        "Citizen Safety",
        "Strategic"
    ],
    "datasets": {
        "2": {
            "label": "Medium",
            "backgroundColor": "#FF9534",
            "data": [
                80,
                103,
                40
            ]
        },
        "1": {
            "label": "Low",
            "backgroundColor": "#FF9534",
            "data": [
                39,
                11
            ]
        },
        "3": {
            "label": "High",
            "backgroundColor": "#FF9534",
            "data": [
                8,
                6,
                28
            ]
        },
        "4": {
            "label": "Extreme",
            "backgroundColor": "#FF9534",
            "data": [
                7
            ]
        }
    }
}

但我想要的实际输出是下面的一个

{
    "labels": [
        "Tactical",
        "Citizen Safety",
        "Strategic"
    ],
    "datasets": {
        "2": {
            "label": "Medium",
            "backgroundColor": "#FF9534",
            "data": [
                80,
                103,
                40
            ]
        },
        "1": {
            "label": "Low",
            "backgroundColor": "#FF9534",
            "data": [
                39,
                0,
                11
            ]
        },
        "3": {
            "label": "High",
            "backgroundColor": "#FF9534",
            "data": [
                8,
                6,
                28
            ]
        },
        "4": {
            "label": "Extreme",
            "backgroundColor": "#FF9534",
            "data": [
                0,
                7,
                0
            ]
        }
    }
}

我的意思是当我循环遍历来自$array 数组对象的标签时,当任何数组对象都没有标签对象(如中、低、高、极端)时,我试图将计数分配为 0,即没有发生在响应中。有人可以帮我解决我在这里缺少的东西吗? 你可以在这里查看代码的执行https://sandbox.onlinephpfunctions.com/code/398b2d1aa892e898a72fb053e981519e3215a053

请查看下图以了解输出的差异

【问题讨论】:

  • 我看不出这些输出之间有什么区别。而不是说“这就是我想要的”并期望我们玩“找出差异”,您应该描述您想要的,它可能会帮助您找出过程中的问题。
  • @miken32 请检查屏幕截图以获得澄清,我希望这能让您了解我正在尝试做什么
  • @NicoHaase 如果您看到此链接sandbox.onlinephpfunctions.com/code/…,您可以看到我尝试过的每个循环都有一个
  • 请通过编辑将所有尝试添加到此问题。另外,分享您尝试解决问题的方法

标签: php arrays laravel foreach


【解决方案1】:

让我们以数组中的第二个元素为例,如下所示

'labels' => 
        array (size=3)
          4 => 
            array (size=3)
              'id' => int 4
              'risk' => string 'Extreme' (length=7)
              'count' => int 7
          2 => 
            array (size=3)
              'id' => int 2
              'risk' => string 'Medium' (length=6)
              'count' => int 103
          3 => 
            array (size=3)
              'id' => int 3
              'risk' => string 'High' (length=4)
              'count' => int 6

对于此元素,您希望结果数组包含标签 Low (id is 1)) 的 0。为了创建结果集,您将使用 foreach ($value['labels'] as $label) 迭代此数组并为数据分配值$dataset[$label['id']]['data'][] = $label['count'];

到目前为止一切都很好。但是,请注意,当 php 遍历此数组时,它将只有 3 个键,即。 4, 2 & 3。它正在正确填充结果数组。

现在我们还期望它填充 id 1 的计数,该数组甚至不存在于该数组中,并且在特定迭代中从未遇到过。因此变量$label['id'] 永远不会等于赋值行$dataset[$label['id']]['data'][] = $label['count']; 中的1

您可以通过在每个数组中插入计数为 0 的缺失元素来解决此问题。

为了做到这一点,我们需要一个所有风险标签的列表,并以它们的 id 作为键。我们可以使用array_columnarray_merge_recursive 来做到这一点。

请注意array_merge_recursive 中的...。这称为 splat 运算符,用于unpack 数组。 You can read more about splat on this questions

$riskArray = array_column($array, 'labels');
$riskArrayFiltered = array_column(array_merge_recursive(...$riskArray), 'risk', 'id');

一旦我们有了所有风险的列表,我们需要做的就是遍历$array,检查并添加任何缺失的风险标签。

foreach ($array as $key => $value){
    $labelArray = $value['labels'];
    $missingRiskTypes = array_diff(array_keys($riskArrayFiltered), array_keys($labelArray));
    foreach ($missingRiskTypes as $missingRiskId){
        $array[$key]['labels'][$missingRiskId] =
            ['id' => $missingRiskId, 'risk' => $riskArrayFiltered[$missingRiskId], 'count' => 0];
    }
}

现在你可以在这个数组上运行你的代码来得到你正在寻找的东西。

我建议您在创建时尝试更改数组的结构。应该有一种更简单、更简洁的方法来完成您正在尝试做的事情。

Here is a working example

【讨论】:

  • 我的错,我从没想过如果我在初始数组中创建缺少的标签会更容易,而不是我总是以我想要的方式格式化数组。感谢一百万的帮助:)
猜你喜欢
  • 1970-01-01
  • 2017-11-09
  • 1970-01-01
  • 2011-06-09
  • 2020-05-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多