我在找出如何在特定数组中搜索索引/匹配值时遇到了麻烦.

我可以列出并格式化所有内容,但我不确定发生了什么(它看起来不像数组中的数组,或者是吗?),也不知道如何在这种特定情况下搜索特定的索引/值.

示例:

{
  "AppName": {
    "date": "20230801",
    "version": "6.8.48"
  },
  "Invoices": [
    {
      "Administration": {
        "id": 2,
        "code": "TEST",
        "description": "Test Administration"
      },
      "Invoice": {
        "id": 4350,
        "type": "",
        "invoiceNumber": 2340323,
        "date": "2023-07-31T00:00:00.000Z",
        "dueDate": "2023-08-14T00:00:00.000Z",
        "amount": 196.3
      },
      "Relation": {
        "nr": 102616,
        "name": "John Doe"
      },
      "TermsOfPayment": {
        "id": 11,
        "description": "Prepayment"
      }
    },
    {
      "Administration": {
        "id": 2,
        "code": "TEST",
        "description": "Test Administration"
      },
      "Invoice": {
        "id": 4351,
        "type": "",
        "invoiceNumber": 2340324,
        "date": "2023-07-31T00:00:00.000Z",
        "dueDate": "2023-08-14T00:00:00.000Z",
        "amount": 748.3
      },
      "Relation": {
        "nr": 102158,
        "name": "Jane Doe"
      },
      "TermsOfPayment": {
        "id": 11,
        "description": "Prepayment"
      }
    },
  ]
}

在列出我使用的值时:

$parsed = json_decode($received, true);

if ($parsed['AppName'] == true) {

    $obj = json_decode($received);

    $invoices = $obj->Invoices;

    foreach ($invoices as $key => $value) {
        $invoice_number = $value->Invoice->invoiceNumber;
        $invoice_amount = $value->Invoice->amount;

        print "<br>".$invoice_number;
        print "<br>".$invoice_amount."<br>";
    }

现在,下一步是搜索特定发票编号的金额.所以搜索2340324需要返回748.3

我try 使用ARRAY_SEARCH和ARRAY_COLUMN搜索/匹配关键字,但得到的结果都是空值.我一定是做错了什么,我猜这和"数组深度"有关?

任何关于如何处理这一问题的建议都将不胜感激.

推荐答案

因此,您try 了ARRAY_COLUMN()和ARRAY_Search().鼻子不错.

好消息是:我们在ARRAY_COLUMN()中搜索事实,因为发票编号是唯一的自然数,所以我们可以使用ARRAY_COLUMN()的索引功能.

但在此之前,你首先应该考虑的是和Foreach一起做:

$amount = null;
foreach ($obj->Invoices as $invoice) {
    if (2340324 === $invoice->Invoice->invoiceNumber) {
        $amount = $invoice->Invoice->amount;
        break;
    }
}
# $amount: 748.3

现在,让我们看看如何使用函数来完成这项工作.

_

由于json_decode()不支持这种情况,因此更正了$received中的逗号:

$obj = json_decode($received, false, 512, JSON_THROW_ON_ERROR);

ARRAY_COLUMN()的第一个参数始终是要遍历的内容/index(SUBJECT),名为$ARRAY.(因为PHP7.0.0也支持对象.)

第二个是以数组值的形式返回的内容,名为$Column_Key.

第三个是使用什么值作为索引并命名为$INDEX_KEY.

返回类型始终为array.

然后,我们只能使用ARRAY_COLUMN()创建一个按发票编号索引的所有发票金额的数组,然后使用2340324的数组访问来获取金额:

$amount = array_column(
    array: array_column(
        array: $obj->Invoices,
        column_key: 'Invoice'
    ),
    column_key: 'amount',
    index_key: 'invoiceNumber',
)[2340324] ?? null;

所以答案是ARRAY_COLUMN()两次.首先获取发票数组,然后通过InvoiceNumber为金额编制索引/将其映射到InvoiceNumber.

如果您觉得这段代码很难读懂(以下),您可以使用一些中间变量并重新排列:

$invoices = array_column($obj->Invoices, 'Invoice');

$invoiceAmountsByInvoiceNumber = array_column($invoices, 'amount', 'invoiceNumber');

$amount = $invoiceAmountsByInvoiceNumber[2340324] ?? null;

# $amount: 748.3

或者使用Foreach方法,因为它具有较少的间接性.

https://php.net/array_column

备注

JSON文本带有类型化的对象和对象集合,这使得遍历它变得很困难,因为它增加了递归深度,您总是需要再深入一层.

因此,要搜索标量值,始终需要映射其属性.

标准操作不能直接应用,需要两次ARRAY_COLUMN(),首先构建对象数组,然后执行标准搜索:"Most efficient way to search for object in an array by a specific property's value"


我用这个名字来称呼它们,我不知道这个惯例从何而来,也不知道还有什么其他的命名.我对这方面的 comments 持开放态度.

Php相关问答推荐

在WooCommerce Checkout帐单地址字段后插入自定义按钮

根据用户组或登录状态显示或隐藏定价后添加的文本

在函数内部获取一致的单选按钮值以更新WordPress用户数据

如何使用ms graph php sdk v2列出具有已知路径的DriveItem的子项

Laravel 10 -扩展现有的artisan命令?

无法在Laravel/Vue停靠容器中启动MySQL

EBay Inventory API createOrReplaceInventoryItem出错

WooCommerce-在选定类别中每消费X个金额即可添加免费礼物

将文件添加到存档,而不重建存档

如何保存基于用户 Select 的复选框 Select 模式

在WooCommerce获取所有具有全球产品属性品牌的简单产品

如何在PHP中根据会话将用户重定向到不同的页面?

WooCommerce:如果订单总数为零,则隐藏本地取货运输选项

htaccess 重定向子域错误的 url

Golang - Html 模板:如何创建导航项 - 子菜单?我找不到怎么做

基于WooCommerce中的产品变体自定义感谢页面跳转

Laravel 路由参数中的 ":" 是什么?

来自 GoDaddy 的邮箱在 Gmail 中显示为via

Laravel 10 单元测试看不到来自 Artisan Command 的数据库更改

多排序子数组 - 包含范围数据的子数组