#php #html
#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) amp;amp; 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
)
)
)
Очевидно, что это должно работать для любого количества. Мне нужно будет сгенерировать ошибку, если все введенные части не разделяются поровну на основе значения ключа.
Комментарии:
1. Не могли бы вы использовать всего несколько вещей, если вы собираетесь публиковать образцы данных,
var_export
поскольку это создает массивы, которые можно использовать в коде.
Ответ №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(amp;$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
)
)
)
В этом случае мы можем просто использовать 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(amp;$item)use($qty_chosen){
$item['quantity'] = $item['quantity'] / $qty_chosen;
});
Разница в том, что array_walk
это более «волшебный» из 2, поскольку на самом деле он не предназначен для обновления массива, где as array_map
специально разработан для этого. Мы можем сделать это с помощью array_walk_*
функции (ов), но мы должны передать $item
по ссылке с помощью amp;
(что является совершенно другим уроком).
Лично я предпочитаю array_map
в этом случае, поскольку это немного более читабельно. Если вы хотите получить действительно особенное (или чувствуете себя особенно ленивым), вы можете разделить следующим образом:
$item['quantity'] /= $qty_chosen;
Что-то вроде .=
или =
и т.д. Я никогда не использую это, я предполагаю, что я недостаточно разделяю, чтобы действительно подумать об этом … ?
В любом случае, надеюсь, это поможет.
Комментарии:
1. зачем вам это
array_walk_recursive
, когда доступ к индексу был бы здесь совершенно разумным, особенно когда вы заметили недостаток? ;o/2.
when an index access would be perfectly reasonable here
— по сути, вам нужно сделать то же самое, что и переход по массиву перед циклом for. Потому что в цикле for вам понадобится еще один цикл (но вы будете повторять это без необходимости каждый раз). Для каждой итерации цикла for требуется весь массив, минус один элемент, разделенный на{n}
или$parts
в моем коде. Итак, вы видите, что бессмысленно изменять это в цикле for, а затем мы делаем это раньше, что аналогично тому, что делает array walk. Мы бы просто делали это вручную.3. с доступом к индексу я имел в виду вместо рекурсивного, просто
array_walk
и$item['quantity'] = $item['quantity'] / $qty_chosen;
4. это было проще набирать
_recursive
. lol В этом случаеarray_map
лучше.
Ответ №2:
$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);