在 PHP 中关联多维数组中的数据

发布于 2024-12-09 06:16:26 字数 2326 浏览 0 评论 0原文

感谢您的帮助。这个把我难住了。我们从这个开始:

Array
(
[numCols] => 8
[timePointLabel1] => Week1
[timePointLabel4] => Week2
[timePointLabel7] => Week3
[0] => Array
    (
        [Location0_name] => Name1
        [colText01] => 2
        [colText07] => 4
    )
[1] => Array
    (
        [Location1_name] => Name2
        [colText11] => 9
        [colText14] => 7
    )
)

我希望 timePointLabelsNNN 中的 NNN 按数字顺序排列,从 0 开始。当前 NNN 是 1、4、7。

我们还有一个数组中的数组。 colTextN字段中的N与时间点标签相关。例如,timePointLabel4 与 colText04、colText14 和任何其他以 4 结尾的 colText 相关联。

我想出了如何动态重新排序 NNN,所以我得到了:

Array
(
[numCols] => 8
[timePointLabel0] => Week1
[timePointLabel1] => Week2
[timePointLabel2] => Week3
[0] => Array
    (
        [Location0_name] => Name1
        [colText01] => 2
        [colText07] => 4
    )
[1] => Array
    (
        [Location1_name] => Name2
        [colText11] => 9
        [colText14] => 7
    )
)

See the NNNs in the timePointLabelNNNs now are 0, 1, 2.

我是怎么做到的?使用这段代码:

$timePointLabelCount = preg_grep("/^timePointLabel(\d)+$/",array_keys($this->data));

// go through the time point label array and create a new array to use
// it is assigned the correct order of keys, starting with 0 (since arrays start with 0 anyway)
foreach ($timePointLabelCount as $timePointCustom) {
    $timePointCustomArray[] = $this->data[$timePointCustom];
    unset($this->data[$timePointCustom]);
}

$timePointNum = 0;
// insert the correct timepoint data, in the correct order, into the array
foreach ($timePointCustomArray as $setTimePointData) {
    $this->data['timePointLabel' . $timePointNum] = $setTimePointData;
    $timePointNum++;
}

但是 colTexts 仍然是一个问题。对于 colTextN 中的 N 值,任何 1 现在都应该是 0,4 现在应该是 1,7 现在应该是 2。

所以我希望我的最终数组看起来像这样:

Array
(
[numCols] => 8
[timePointLabel0] => Week1
[timePointLabel1] => Week2
[timePointLabel2] => Week3
[0] => Array
    (
        [Location0_name] => Name1
        [colText00] => 2
        [colText02] => 4
    )
[1] => Array
    (
        [Location1_name] => Name2
        [colText10] => 9
        [colText11] => 7
    )
)

我怀疑这将需要foreach 循环的一些巧妙用法。

Thank you for any help. This one has me stumped. We start with this:

Array
(
[numCols] => 8
[timePointLabel1] => Week1
[timePointLabel4] => Week2
[timePointLabel7] => Week3
[0] => Array
    (
        [Location0_name] => Name1
        [colText01] => 2
        [colText07] => 4
    )
[1] => Array
    (
        [Location1_name] => Name2
        [colText11] => 9
        [colText14] => 7
    )
)

I want the NNN in the timePointLabelsNNNs to go in numeric order, starting at 0. Currently the NNNs are 1, 4, 7.

We also have an array within an array. The N in the colTextN fields are related to the time point labels. E.g. timePointLabel4 is associated with colText04, colText14, and any other colText that ends in a single digit of 4.

I figured out how to dynamically reorder the NNNs and so I am getting this:

Array
(
[numCols] => 8
[timePointLabel0] => Week1
[timePointLabel1] => Week2
[timePointLabel2] => Week3
[0] => Array
    (
        [Location0_name] => Name1
        [colText01] => 2
        [colText07] => 4
    )
[1] => Array
    (
        [Location1_name] => Name2
        [colText11] => 9
        [colText14] => 7
    )
)

See the NNNs in the timePointLabelNNNs are now 0, 1, 2.

How did I do this? With this code:

$timePointLabelCount = preg_grep("/^timePointLabel(\d)+$/",array_keys($this->data));

// go through the time point label array and create a new array to use
// it is assigned the correct order of keys, starting with 0 (since arrays start with 0 anyway)
foreach ($timePointLabelCount as $timePointCustom) {
    $timePointCustomArray[] = $this->data[$timePointCustom];
    unset($this->data[$timePointCustom]);
}

$timePointNum = 0;
// insert the correct timepoint data, in the correct order, into the array
foreach ($timePointCustomArray as $setTimePointData) {
    $this->data['timePointLabel' . $timePointNum] = $setTimePointData;
    $timePointNum++;
}

But the colTexts are still an issue. For the N values in colTextN, anything that is 1 should now be a 0, the 4 should now be a 1, and the 7s should now be a 2.

So I want my final array to look like this:

Array
(
[numCols] => 8
[timePointLabel0] => Week1
[timePointLabel1] => Week2
[timePointLabel2] => Week3
[0] => Array
    (
        [Location0_name] => Name1
        [colText00] => 2
        [colText02] => 4
    )
[1] => Array
    (
        [Location1_name] => Name2
        [colText10] => 9
        [colText11] => 7
    )
)

I suspect this will require some clever usage of a foreach loop.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

独孤求败 2024-12-16 06:16:26

您无法重命名键而不污染同一数组中的顺序,但您可以构建一个新数组(并稍后取消设置前一个数组):

$i = 0;
$search = 'timePointLabel';
$reordered = array();
foreach($array as $key => &$value)
{
   if (0 === strpos($key, $search))
   {
       $key = $search . $i++;
   }
   $reordered[$key] =& $value;
}
unset($value);
$array = &$reordered;
unset($reordered);
print_r($array);

演示

编辑:要解决子键的问题,您需要获取数字的映射并将这些映射以相同的方式应用于子键大批。原理实际上是相同的+使用地图:

$i = 0;
$search = 'timePointLabel';
$subsearch = 'colText';
$reordered = array();
$map = array();
foreach($array as $key => &$value)
{
   if (0 === strpos($key, $search))
   {
        $digit = NULL;
        sscanf($key, $search.'%d', $digit);
        if (NULL === $digit || $digit > 9) throw new Exception(sprintf('Invalid Key %d.', $key));
        $map[$digit] = $i;
        $key = $search . $i++;
   }
   elseif (is_int($key) && is_array($value))
   {
        $subreordered = array();
        foreach($value as $subkey => &$subvalue)
        {
            if (0 === strpos($subkey, $subsearch))
            {
                $lastPos = strlen($subkey)-1;
                $last = $subkey[$lastPos];
                if (isset($map[$last]))
                {
                    $subkey[$lastPos] = $map[$last];
                }
            }
            $subreordered[$subkey] = &$subvalue;
        }
        unset($subvalue);
        $value =& $subreordered;
        unset($subreordered);
   }
   $reordered[$key] =& $value;
}
unset($value);
unset($map);
$array = &$reordered;
unset($reordered);
print_r($array);

You can not rename keys w/o tainting the order in the same array, but you could build a new array (and unset the previous one later on):

$i = 0;
$search = 'timePointLabel';
$reordered = array();
foreach($array as $key => &$value)
{
   if (0 === strpos($key, $search))
   {
       $key = $search . $i++;
   }
   $reordered[$key] =& $value;
}
unset($value);
$array = &$reordered;
unset($reordered);
print_r($array);

Demo

Edit: To solve this for the sub-keys, you need to obtain the mapping of the digits and apply those the same way on the sub-array. The principle is actually identical + using the map:

$i = 0;
$search = 'timePointLabel';
$subsearch = 'colText';
$reordered = array();
$map = array();
foreach($array as $key => &$value)
{
   if (0 === strpos($key, $search))
   {
        $digit = NULL;
        sscanf($key, $search.'%d', $digit);
        if (NULL === $digit || $digit > 9) throw new Exception(sprintf('Invalid Key %d.', $key));
        $map[$digit] = $i;
        $key = $search . $i++;
   }
   elseif (is_int($key) && is_array($value))
   {
        $subreordered = array();
        foreach($value as $subkey => &$subvalue)
        {
            if (0 === strpos($subkey, $subsearch))
            {
                $lastPos = strlen($subkey)-1;
                $last = $subkey[$lastPos];
                if (isset($map[$last]))
                {
                    $subkey[$lastPos] = $map[$last];
                }
            }
            $subreordered[$subkey] = &$subvalue;
        }
        unset($subvalue);
        $value =& $subreordered;
        unset($subreordered);
   }
   $reordered[$key] =& $value;
}
unset($value);
unset($map);
$array = &$reordered;
unset($reordered);
print_r($array);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文