[
1 => [
'level' => 1,
'process' => 60%,
'setting' => [
'data1' => 1,
'data2' => 2,
'data3' => 3,
],
],
2 => [
'level' => 2,
'process' => 50%
'setting' => [
'data1' => 1,
'data2' => 2,
'data3' => 3,
],
],
3 => [
'level' => 3,
'process' => 70%
'setting' => [
'data1' => 1,
'data2' => 2,
'data3' => 3,
],
],
];
Цитата (Appaloosa @ 29.09.2023 - 06:33) |
Подскажите, пожалуйста, можно ли разделить на уровни вложенности строку и каждому уровню вложенности задать процент (где между фигурной скобкой и прямой чертой идет значение). Например, такая строка: { 1 уровень - 1 | 1 уровень - 2 { 2 уровень - 1 | 2 уровень - 2 } } Чтобы в результате получилась строка: { 50%: 1 уровень - 1 | 50%: 1 уровень - 2 { 25%: 2 уровень - 1 | 25%: 2 уровень - 2 } } Примерно по такому принципу. Не только на 2 уровень, но и на более глубокие уровни вложенности. |
// 1. Побить строку на токены: {, }, |, payload (всё остальное)
function buildTokens($input)
{
return preg_split("/(\{|}|\\|)/", $input, -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY);
}
// 2. Построить дерево
class Node
{
public $text;
public $percent;
public $children;
public function __construct($text = '')
{
$this->text = $text;
$this->percent = 0;
$this->children = [];
}
}
function buildTree($tokens)
{
$stack = new SplStack();
$root = new Node();
$currentNode = $root;
$level = 0;
foreach ($tokens as $token) {
$token = trim($token);
if ($token === '') {
continue;
}
if ($token === '{') {
if ($level > 0) {
if (count($currentNode->children) === 0) {
$currentNode->children[] = new Node();
}
$currentNode = end($currentNode->children);
}
$stack->push($currentNode);
$level++;
} elseif ($token === '}') {
if ($node = $stack->pop()) {
$currentNode = $node;
}
$level--;
if ($level === 1) {
$currentNode = $root;
}
} elseif ($token !== '|') {
$currentNode->children[] = new Node($token);
}
}
return $root->children;
}
// 3. Проставить проценты (имея дерево это сделать легко)
function calculatePercents(array $nodes, $percent = 100)
{
$percentValue = count($nodes) > 0 ? $percent / count($nodes) : $percent;
foreach ($nodes as $node) {
$node->percent = $percentValue;
calculatePercents($node->children, $percentValue);
}
}
// 4. Собрать строку из дерева
function buildString(array $nodes)
{
$str = '';
foreach ($nodes as $i => $node) {
$str .= sprintf(' %d%%: %s ', $node->percent, $node->text);
if ($i < count($nodes) - 1) {
$str .= ' | ';
}
if (count($node->children) > 0) {
$str .= '{' . buildString($node->children) . '}';
}
}
return $str;
}
// 5. Ну и все вместе
$s = '{ 1 уровень - 1 | 1 уровень - 2 { 2 уровень - 1 | 2 уровень - 2 } }';
$tokens = buildTokens($s);
$tree = buildTree($tokens);
calculatePercents($tree);
echo '{' . buildString($tree) . '}';