按键拆分和分组数组

时间:2018-08-27 21:35:06

标签: php arrays grouping

好的,我已经进行了一些搜索,但是没有找到答案,因此,我将对此进行一下介绍。

我有一个JSON文件,可以吐出以下信息:

[
    {
        "Contact name(s)": "Person 1, Person 2",
        "Contact title(s)": "Head Comacho, Other Guy",
        "Contact email(s)": "email1@email.net, email@email.com",
        "Contact phone": "123-456-7890, 789-456-1230",
    },
    {   
        "Contact name(s)": "Some Dude",
        "Contact title(s)": "Cool Title",
        "Contact email(s)": "things@email.com",
        "Contact phone": "555-555-5555",
    },
        "Contact name(s)": "",
        "Contact title(s)": "",
        "Contact email(s)": "",
        "Contact phone": "",
    }
]

不幸的是,数据通过这种方式命名。从我手中无论如何,我必须得到它,以便具有多个联系人的联系人将分组到自己的数组中。这是它的样子:

Array
(
    [0] => Array
        (
            [contact_name] => Person 1
            [contact_title] => Head Comacho
            [contact_email] => email1@email.net
            [contact_phone] => 123-456-7890
        )

    [1] => Array
        (
            [contact_name] => Person 2
            [contact_title] => Other Title
            [contact_email] => email@email.com
            [contact_phone] => 789-456-1230
        )
)
Array
(
    [0] => Array
        (
            [contact_name] => Some Dude
            [contact_title] => Cool Title
            [contact_email] => things@email.com
            [contact_phone] => 555-555-5555
        )
)
Array
(
    [0] => Array
        (
            [contact_name] => 
            [contact_title] => 
            [contact_email] => 
            [contact_phone] => 
        )
)

我能够将数据转换为自己的数组,如下所示:

Array
(
    [contact_name] => Array
        (
            [0] => Person 1
            [1] => Person 2
        )

    [contact_title] => Array
        (
            [0] => Head Comacho
            [1] => Other Guy
        )

    [contact_email] => Array
        (
            [0] => email1@email.net
            [1] => email@email.com
        )

    [contact_phone] => Array
        (
            [0] => 123-456-7890
            [1] => 789-456-1230
        )

)

Array
(
 .....etc
)

我将如何像第一个示例一样获得它?

很抱歉,如果以前已经回答过,我不确定该如何表达我的问题。任何帮助都将受到赞赏。

4 个答案:

答案 0 :(得分:2)

我认为该脚本可以完成您想要的操作。我创建了一个函数split_contacts,该函数将解码后的数组中的每个条目都包含在内,并将值(例如"Person 1, Person 2" => [“ Person 1”,“ Person 2”])拆分为由数组索引的数组对象键,它们由preg_replace按摩成您想要的形式(例如"Contact name(s)" => "contact_name")。请注意,也许可以使用str_replace而不是preg_replace,但是我想让代码在键值格式方面保持灵活性。

$json = '[
    {
        "Contact name(s)": "Person 1, Person 2",
        "Contact title(s)": "Head Comacho, Other Guy",
        "Contact email(s)": "email1@email.net, email@email.com",
        "Contact phone": "123-456-7890, 789-456-1230"
    },
    {   
        "Contact name(s)": "Some Dude",
        "Contact title(s)": "Cool Title",
        "Contact email(s)": "things@email.com",
        "Contact phone": "555-555-5555"
    },
    {
        "Contact name(s)": "",
        "Contact title(s)": "",
        "Contact email(s)": "",
        "Contact phone": ""
    }
]';
$arr = json_decode($json, true);

function split_contact($contact) {
    $contacts = array();
    foreach ($contact as $key => $values) {
        $key = strtolower(preg_replace(array('/\(s\)$/', '/\s+/'), array('', '_'), $key));
        foreach (explode(',', $values) as $index => $value) {
            $contacts[$index][$key] = trim($value);
        }
    }
    return $contacts;
}

$newarr = array();
foreach ($arr as $contact) {
    $newarr[] = split_contact($contact);
}

print_r($newarr);

输出:

Array
(
    [0] => Array
        (
            [0] => Array
                (
                    [contact_name] => Person 1
                    [contact_title] => Head Comacho
                    [contact_email] => email1@email.net
                    [contact_phone] => 123-456-7890
                )    
            [1] => Array
                (
                    [contact_name] =>  Person 2
                    [contact_title] =>  Other Guy
                    [contact_email] =>  email@email.com
                    [contact_phone] =>  789-456-1230
                )    
        )    
    [1] => Array
        (
            [0] => Array
                (
                    [contact_name] => Some Dude
                    [contact_title] => Cool Title
                    [contact_email] => things@email.com
                    [contact_phone] => 555-555-5555
                )    
        )    
    [2] => Array
        (
            [0] => Array
                (
                    [contact_name] => 
                    [contact_title] => 
                    [contact_email] => 
                    [contact_phone] => 
                )    
        )    
)

答案 1 :(得分:1)

如果您可以确保多个人的json对象始终包含完全相同数量的元素,那么您可以执行以下操作:

<?php

$json = '[
    {"Contact name(s)": "Person 1, Person 2", "Contact title(s)": "Head Comacho, Other Guy", "Contact email(s)": "email1@email.net, email@email.com", "Contact phone": "123-456-7890, 789-456-1230"},
    {"Contact name(s)": "Some Dude", "Contact title(s)": "Cool Title", "Contact email(s)": "things@email.com", "Contact phone": "555-555-5555"},
    {"Contact name(s)": "", "Contact title(s)": "", "Contact email(s)": "", "Contact phone": ""}
]';

$jsonA = json_decode($json, true);

$result = [];
$maxLen = 0;
foreach ($jsonA as &$obj) {
    foreach ($obj as $k => $v) {
        if (!isset($result[$k])) $result[$k] = [];
        foreach (explode(',', $v) as $av) $result[$k][] = trim($av);
        $maxLen = max($maxLen, count($result[$k]));
    }
}

$objects = [];
for ($i=0; $i<$maxLen; $i++) {
    $object = [];
    foreach (array_keys($result) as $k) $object[$k] = isset($result[$k][$i]) ? $result[$k][$i] : '';
    $objects[] = $object;
}

echo '<pre>';
print_r($objects);

它打印:

Array
(
    [0] => Array
        (
            [Contact name(s)] => Person 1
            [Contact title(s)] => Head Comacho
            [Contact email(s)] => email1@email.net
            [Contact phone] => 123-456-7890
        )

    [1] => Array
        (
            [Contact name(s)] => Person 2
            [Contact title(s)] => Other Guy
            [Contact email(s)] => email@email.com
            [Contact phone] => 789-456-1230
        )

    [2] => Array
        (
            [Contact name(s)] => Some Dude
            [Contact title(s)] => Cool Title
            [Contact email(s)] => things@email.com
            [Contact phone] => 555-555-5555
        )

    [3] => Array
        (
            [Contact name(s)] => 
            [Contact title(s)] => 
            [Contact email(s)] => 
            [Contact phone] => 
        )

)

答案 2 :(得分:1)

我来到了这个解决方案:

trait/object

答案 3 :(得分:0)

如果这是我的项目,这就是我要做的事情以及原因...

  1. 您需要将每个数据子集彼此分开,因此请使用$temp作为外循环迭代之间的临时存储。必须在每个新的$set的开始处重置临时数组,并且必须将临时数组数据传输到$result数组以维护原始设置的索引。
  2. explode()最好用作“逗号空间”作为定界符参数-这样就不必调用任何其他函数来拖延剩余的空间。
  3. 因为您的新旧密钥是已知的和静态的,所以对关联的“转换”数组进行硬编码将节省大量的迭代函数调用,并大大减少代码膨胀。我还将争辩说,这使您可以更轻松地控制密钥准备工作,并且将来的开发人员将能够迅速理解您的代码在做什么。

代码:(Demo

$json = '[
    {"Contact name(s)": "Person 1, Person 2", "Contact title(s)": "Head Comacho, Other Guy", "Contact email(s)": "email1@email.net, email@email.com", "Contact phone": "123-456-7890, 789-456-1230"},
    {"Contact name(s)": "Some Dude", "Contact title(s)": "Cool Title", "Contact email(s)": "things@email.com", "Contact phone": "555-555-5555"},
    {"Contact name(s)": "", "Contact title(s)": "", "Contact email(s)": "", "Contact phone": ""}
]';
$array = json_decode($json, true);

$trans = [
    "Contact name(s)" => "contact_name",
    "Contact title(s)" => "contact_title",
    "Contact email(s)" => "contact_email",
    "Contact phone" => "contact_phone"    
];

foreach ($array as $set) {
    $temp = [];
    foreach ($set as $key => $data) {
        foreach (explode(', ', $data) as $index => $value) {
            $temp[$index][$trans[$key]] = $value;     
        }
    }
    $result[] = $temp;
}
var_export($result);

输出:

array (
  0 => 
  array (
    0 => 
    array (
      'contact_name' => 'Person 1',
      'contact_title' => 'Head Comacho',
      'contact_email' => 'email1@email.net',
      'contact_phone' => '123-456-7890',
    ),
    1 => 
    array (
      'contact_name' => 'Person 2',
      'contact_title' => 'Other Guy',
      'contact_email' => 'email@email.com',
      'contact_phone' => '789-456-1230',
    ),
  ),
  1 => 
  array (
    0 => 
    array (
      'contact_name' => 'Some Dude',
      'contact_title' => 'Cool Title',
      'contact_email' => 'things@email.com',
      'contact_phone' => '555-555-5555',
    ),
  ),
  2 => 
  array (
    0 => 
    array (
      'contact_name' => '',
      'contact_title' => '',
      'contact_email' => '',
      'contact_phone' => '',
    ),
  ),
)

您会发现此解决方案不仅简洁,准确而且易于阅读;这也是非常有效的,因为在整个过程(explode())中只有一个迭代的函数调用。