从多维数组中提取和分组数据

时间:2014-10-11 13:07:19

标签: php arrays multidimensional-array grouping

我想从多维数组中打印出信息。

这是我的数组结构:

// A two-dimensional array
$cars=array
(
    array('service' => "Windows8",'host' => Sydney1,'state' => on),
    array('service' => "unix",'host' => Newyork2,'state' => off),
    array('service' => "Windows8",'host' => Singapore3,'state' => on),
    array('service' => "unix",'host' => Tokyo4,'state' => off),
    array('service' => "Windows8",'host' => Tokyo4,'state' => on),
);

我想安排数据打印出以下内容:

按服务分组的数据:所需的输出:

Windows8 (3): Sydney1 (on), Singapore3 (on), Tokyo4 (on) 
unix (2): Newyork2 (off), Tokyo4 (off)

按主机分组的数据:所需的输出:

Sydney1 (1): Windows8 (on)
Newyork2 (1): unix (off)
Singapore3 (1): Windows8 (on)
Tokyo4 (2): unix (off), Windows8 (on)

这是我到目前为止尝试过的代码:

    $arr = array();

    foreach($cars as $key => $item)
    {
       $arr[$item['service_name']][$key] = $item;
    }
    echo '<pre>';    
    print_r($arr);
    echo '</pre>';

    $size = sizeof($arr);
    $i=1;
    foreach($arr as $key => $item)
    {
        echo $key;
    }

3 个答案:

答案 0 :(得分:1)

操纵数组的技巧是将它们安排到数据结构中,以便您轻松检索所需的数据。

$cars=array (
       array('service' => "Windows8",'host' => 'Sydney1','state' => 'on'),
       array('service' => "unix",'host' => 'Newyork2','state' => 'off'),
       array('service' => "Windows8",'host' => 'Singapore3','state' => 'on'),
       array('service' => "unix",'host' => 'Tokyo4','state' => 'off'),
       array('service' => "Windows8",'host' => 'Tokyo4','state' => 'on'),
);

# initialise an array to group data by service and by location
$data = array();

foreach ($cars as $c) {
    # the key is the service name, and the value is an array of host/state pairs
    $data['by_service'][ $c['service'] ][] = array( $c['host'] , $c['state'] );

    # the key is the location name, and the value is an array of service/state pairs
    $data['by_location'][ $c['host'] ][] = array( $c['service'] , $c['state'] );
}

# create a function that we can use to print data from the pairs in the
# data structures above: it creates a string with the first array item
# followed by the second item in brackets
function print_arr ($arr) {
    return $arr[0] . " (" . $arr[1] . ")";
}

# group by service:
foreach ($data['by_service'] as $s => $host) {
    # print the service type, $s, and count the number of hosts
    echo "$s (" . count($host) . "): ";

    # print the details for the individual hosts, using print_arr for the details
    # array_map is an extremely useful function that allows you to apply a function
    # to every member of an array. It saves having to create new arrays or alter
    # the array using foreach and you can include it in an echo statement.
    echo implode(", ", array_map( "print_arr", $host ) ) . "\n";
}

echo "\n\n";

# group by location
foreach ($data['by_location'] as $l => $host) {
    # print the location and the count for the number of hosts
    echo "$l (" . count($host) . "): ";
    echo implode(", ", array_map( "print_arr", $host ) ) . "\n";
}

输出:

Windows8 (3): Sydney1 (on), Singapore3 (on), Tokyo4 (on)
unix (2): Newyork2 (off), Tokyo4 (off)


Sydney1 (1): Windows8 (on)
Newyork2 (1): unix (off)
Singapore3 (1): Windows8 (on)
Tokyo4 (2): unix (off), Windows8 (on)

如果您在代码中迷路了,可能会发现print_r结构的$data有用。

答案 1 :(得分:0)

$cars=array
   (
    array('service'=> "Windows8",'host'=> 'Sydney1','state'   => 'on'),
    array('service'=> "unix",'host'    => 'Newyork2','state'  => 'off'),
    array('service'=> "Windows8",'host'=> 'Singapore3','state'=> 'on'),
    array('service'=> "unix",'host'    => 'Tokyo4','state'    => 'off'),
    array('service'=> "Windows8",'host'=> 'Tokyo4','state'    => 'on'),
   );


    $windows    = array();
    $i          = 0;
    $j          = 0;
while(list($carval, $value) = each($cars))
{

     // echo $key." = ".$value."<br>\n";
     if($value['service']=="Windows8"){
        $windows[$i++] = $value['host']."(".$value['state'].")";            
     }
     else{
        $unix[$j++] = $value['host']."(".$value['state'].")";           
     }


}
echo "Windows8 (".count($windows).") : "; 
foreach($windows as $vall)
{
    echo $vall.", ";
}

echo "<br>Unix (".count($unix).") : "; 

foreach($unix as $vall)
{
    echo $vall.", ";
}

这是第一部分等等我会抓住你的全部......

答案 2 :(得分:0)

<?php

$cars = array
(
    array('service' => 'Windows8','host' => 'Sydney1','state' => 'on'),
    array('service' => 'unix','host' => 'Newyork2','state' => 'off'),
    array('service' => 'Windows8','host' => 'Singapore3','state' => 'on'),
    array('service' => 'unix','host' => 'Tokyo4','state' => 'off'),
    array('service' => 'Windows8','host' => 'Tokyo4','state' => 'on'),
);

// Create the output array
$output = array();
foreach($cars as $car)
{
    // If the service isn't added yet, add it otherwise increase it
    // I do it this way to prevent the php warning
    if(empty($output[$car["service"]]["count"])) $output[$car["service"]]["count"] = 1;
    else $output[$car["service"]]["count"]++;

    // Add the host, only if its not exists on the specific service 
    if(!in_array($car["host"], $output[$car["service"]]["hosts"]))
        $output[$car["service"]]["hosts"][] = $car["host"];

    // Check if the states there within the host as key
    if(!array_key_exists($car["host"], $output[$car["service"]]["states"]))
        $output[$car["service"]]["states"][$car["host"]] = $car["state"];
}

// Create the first output
foreach($output as $service => $data)
{
    $hosts = array();
    foreach($data["hosts"] as $index => $host)
        $hosts[] = $host . "(" . $data["states"][$host] . ")";

    // Combine the hosts to the string
    $hosts = implode(", ", $hosts);

    echo $service . "(" . $data["count"] . ") : " . $hosts;
    echo "<br />"; // HTML new line ?
}

// Now the second output, prepare it
$hosts = array(); // Let's store the hosts here, to make the code simple to read :)
foreach($output as $service => $data)
{
    foreach($data["hosts"] as $index => $host)
        $hosts[$host][] = $service . "(" . $data["states"][$host] . ")";
}

// Print it
foreach($hosts as $hostName => $hostData)
{
    $hostValue = array();

    foreach($hostData as $service)
        $hostValue[] = $service;

    echo $hostName . "(" . count($hostData) . ") \t\t: " . implode(", ", $hostValue);
    echo "<br />"; // HTML new line ?
}