根据关键项值平均划分整个PHP关联数组

时间:2019-03-20 16:59:13

标签: php html

我的第一个帖子在这里。 PHP的新手,我有一部分需要做。制作一个网页,其中可以使用连接的条形码扫描仪将零件快速扫描成阵列。

<form id="results" action="launchresults.php" method="post"></form>
<form id="partslist" action='' method='post'></form>

<input type="text" name="partlist" id="partlist" form="partslist" />
<input type="submit" name='additem' value="Add Item" form="partslist" />
<input type="submit" name="clear" value="clear" form="partslist" />

<?php if (isset($_POST['additem'])) {
   if(!array_key_exists("parts", $_SESSION)) {
      $_SESSION["parts"] = array();
   }
   if(array_key_exists("parts", $_SESSION) && array_key_exists($_POST['partlist'],$_SESSION["parts"])) {
      $increasevalue = $_SESSION["parts"][$_POST['partlist']]['quantity'];
      $_SESSION["parts"][$_POST['partlist']]['quantity'] = $increasevalue+1;
   }
   else {   
      $_SESSION["parts"][$_POST['partlist']] = array("quantity" => 1);
   }
}

if(isset($_POST['clear'])) {
   $_SESSION = array();
}

if(array_key_exists("parts", $_SESSION)):
   foreach ($_SESSION["parts"] as $partlist => $partlist_quantity):
      foreach ($partlist_quantity as $key => $value): ?>
         <input type="text" name="items[]" value="<?php echo $partlist; ?>" />
         <input type="number" name="quantity" value="<?php echo $value; ?>" />
      <?php endforeach; ?>
   <?php endforeach; ?>
<?php endif; ?>

<input type="submit" name="submit" form="results" />

我可以扫描零件条形码以构建阵列。如果零件是我已经扫描过的零件,它将使数量增加1。输入字段是可编辑的,但是代码当前不允许手动更新这些字段。当我单击“提交”时,我将得到如下结果:

    Array
(
    [parts] => Array
        (
            [12345] => Array
                (
                    [quantity] => 6
                )

            [errrt] => Array
                (
                    [quantity] => 2
                )

            [ffggg] => Array
                (
                    [quantity] => 4
                )

            [wefewf] => Array
                (
                    [quantity] => 10
                )

        )

)

我现在要弄清楚的是如何找到关键零件,查看零件的数量,然后按该值将所有零件划分为相等的数组。因此,上面的主要部分是“ errrt”,那么我想将所有内容都除以2,最后得到类似下面的内容...

Array
(
    [errrt1] => Array
        (
            [12345] => Array
                (
                    [quantity] => 3
                )

            [ffggg] => Array
                (
                    [quantity] => 2
                )

            [wefewf] => Array
                (
                    [quantity] => 5
                )

        )
    [errrt2] => Array
        (
            [12345] => Array
                (
                    [quantity] => 3
                )

            [ffggg] => Array
                (
                    [quantity] => 2
                )

            [wefewf] => Array
                (
                    [quantity] => 5
                )

        )
)

这显然需要任何数量的工作。如果输入的所有部分均未根据键值均分,我将需要生成错误。

2 个答案:

答案 0 :(得分:1)

赞:

$a = array (
    'parts' => 
    array (
        12345 => 
        array (
            'quantity' => 6
        ),
        'errrt' => 
        array (
            'quantity' => 2
        ),
        'ffggg' => 
        array (
            'quantity' => 4
        ),
        'wefewf' => 
        array (
            'quantity' => 10
        )
    )
);

$choice = 'errrt';
//localize
$parts = $a['parts'];

//localize chosen 
$qty_chosen = isset($parts[$choice], $parts[$choice]['quantity']) ? $parts[$choice]['quantity'] : 0;

if(!$qty_chosen) die('Cannot divide by 0');

unset($parts[$choice]); //remove it
array_walk_recursive($parts, function(&$item)use($qty_chosen){
    $item = $item / $qty_chosen;
});

$result = [];
for($i=1;$i<=$qty_chosen; ++$i){
    $result[$choice.$i] = $parts;
}


print_r($result);

输出

Array
(
    [errrt1] => Array
        (
            [12345] => Array
                (
                    [quantity] => 3
                )

            [ffggg] => Array
                (
                    [quantity] => 2
                )

            [wefewf] => Array
                (
                    [quantity] => 5
                )

        )

    [errrt2] => Array
        (
            [12345] => Array
                (
                    [quantity] => 3
                )

            [ffggg] => Array
                (
                    [quantity] => 2
                )

            [wefewf] => Array
                (
                    [quantity] => 5
                )

        )

)

Sandbox

在这种情况下,我们可以简单地使用array_walk_recursive来划分嵌套数量,但是如果数组中还有其他元素,您将无法做到这一点。

如果您还有其他元素可以使用(代替array_walk_recursive):

 $parts = array_map(function($item)use($qty_chosen){
    $item['quantity'] = $item['quantity'] / $qty_chosen;
    return $item;
 }, $parts);

 array_walk($parts, function(&$item)use($qty_chosen){
    $item['quantity'] = $item['quantity'] / $qty_chosen;
 });

区别在于array_walk是2中更“神奇的”,因为它并不是真正用来更新数组的,而array_map是专门为实现此目的而设计的。我们可以使用array_walk_*函数来做到这一点,但是我们必须通过引用$item来传递&(这是另一堂课)。

在这种情况下,我个人更喜欢array_map,因为它更具可读性。如果您想变得特别(或感到特别懒惰),可以这样划分:

 $item['quantity'] /= $qty_chosen;

哪种有点像.=+=等。我从不使用它,我想我没有做足够的划分来真正考虑一下...?

无论如何,希望对您有所帮助。

答案 1 :(得分:0)

$array = ['parts' => [
  '12345' => ['quantity' => 6],
  'errrt' => ['quantity' => 2],
  'ffggg' => ['quantity' => 4],
  'wefewf' => ['quantity' => 10],
]];

// i don't know how you determine the main part, but that's your cup of tea ;o)
$mainpart = 'errrt';

// fetching quantity of the main part:
$divider = $array['parts'][$mainpart]['quantity'];

// create the sub part, since they are all identical, 
// we make a sample "pattern", called "divided"
// (you could change the original array instead, 
// but I chose to leave it unchanged)
$divided = [];
foreach($array['parts'] as $partname => $part) {
    // the main part is not part of the pattern
    if($partname == $mainpart) {
        continue;
    }
    // if the quantity of the part is not dividable by
    // main part quantity, abort or whatever
    if($part['quantity'] % $divider != 0) {
        // echo error message or throw Exception or whatever
        // optionally set some flag and break;
        throw new Exception('part '.$partname.' has quantity that cannot be divided by '.$divider);
    }

    // fix the quantity.
    $part['quantity'] = $part['quantity'] / $divider;
    // add the part to the pattern.
    $divided[$partname] = $part;
}

$result = [];
// expand the pattern 
for($i = 1; $i <= $divider; $i++) {
    $result[$mainpart.$i] = $divided;
}


var_export($result);