【问题标题】:Manipulation of php arrayphp数组的操作
【发布时间】:2023-03-31 01:04:01
【问题描述】:

我需要使用从数组中获取的值创建路径结构:

Array
(
    [machineAttribute] => Array
    (
        [0] => TTT 1000 S
        [1] => TTT 1100 S
    )

    [technicalAttribute] => Array
    (
        [0] => Certificate
        [1] => Software
    )

    [languageAttribute] => Array
    (
        [0] => English
        [1] => Spanish
    )

)

所以,我需要创建如下所示的路径:

Array
(
    [0] => TTT 1000 S/Certificate/English
    [1] => TTT 1000 S/Certificate/Spanish
    [2] => TTT 1000 S/Software/English
    [3] => TTT 1000 S/Software/Spanish
    [4] => TTT 1100 S/Certificate/English
    [5] => TTT 1100 S/Certificate/Spanish
    [6] => TTT 1100 S/Software/English
    [7] => TTT 1100 S/Software/Spanish
)  

这是一个完美的场景,我能够使用嵌套的 foreach 解决这个问题:

if (is_array($machineAttributePath))
{
    foreach ($machineAttributePath as $machinePath)
    {
        if (is_array($technicalAttributePath))
        {
            foreach ($technicalAttributePath as $technicalPath)
            {

                if (is_array($languageAttributePath))
                {
                    foreach ($languageAttributePath as $languagePath)
                    {
                        $multipleMachineValuesPath[] = $machinePath . '/' . $technicalPath . '/' . $languagePath);
                    }
                }

            }
        }
    }

    return $multipleMachineValuesPath;
}

但是,问题开始了,如果数组返回混合值,有时返回单个值,有时返回数组。例如:

Array
(
    [machineAttribute] => Array
    (
        [0] => TTT 1000 S
        [1] => TTT 1100 S
        [2] => TTT 1200 S
    )

    [technicalAttribute] => Certificate

    [languageAttribute] => Array
    (
        [0] => English
        [1] => Spanish
    )

)

那么数组应该是这样的:

Array
(
    [0] => TTT 1000 S/Certificate/English
    [1] =>TTT 1000 S/Certificate/Spanish
    [2] => TTT 1100 S/Certificate/English
    [3] => TTT 1100 S/Certificate/Spanish
)

我写了代码,但它真的很乱而且很长而且不能正常工作。我确信这可以以某种方式简化,但我有足够的知识来解决这个问题。如果有人知道如何处理这种情况,请提供帮助。谢谢。

【问题讨论】:

  • 如果是单值,你想要的输出是什么?您想在所有路径中添加该单个值吗?
  • 这是个好问题,我在编辑后的代码中添加了答案。

标签: php arrays recursion


【解决方案1】:

您可以将任何单个值转换为数组,只需通过

  (array) $val

同时,如果$val已经是数组,则不会改变

所以,你可以稍微改变一下所有的foreach

foreach((array) $something....

【讨论】:

  • 伟大而如此简单...:) 尝试并像魅力一样工作。$pathArr = array(); foreach($arr['machineAttribute'] as $m) { foreach($arr['technicalAttribute'] as $t) { foreach((array) $arr['languageAttribute'] as $l) { $pathArr[] = implode('/',array($m,$t,$l)); } } }
【解决方案2】:

如果您需要一些简单的东西,您可以通过编写简单的单独函数(将其命名为“force_array”)将标量值转换为数组。如果参数不是数组,则将参数包装到数组的函数。

function force_array($i) { return is_array($i) ? $i : array($i); }

//...

foreach (force_array($machineAttributePath) as $machinePath)
{
    foreach (force_array($technicalAttributePath) as $technicalPath)
    {
        foreach (force_array($languageAttributePath) as $languagePath)
        {
            $multipleMachineValuesPath[] = $machinePath . '/' . $technicalPath . '/' . $languagePath;
        }
    }
}

return($multipleMachineValuesPath);

【讨论】:

  • 这段代码很好用。我已将 200 多行代码减少到 10 行 :)。谢谢你,塞尔吉。
【解决方案3】:

您也可以这样做而不会搞砸。只需创建输入数组的笛卡尔,最后使用/ 内爆生成的数组。希望这会有所帮助:)

<?php
function cartesian($input) {
    $result = array();

    while (list($key, $values) = each($input)) {

        if (empty($values)) {
            continue;
        }
        if (empty($result)) {
            foreach($values as $value) {
                $result[] = array($key => $value);
            }
        }
        else {

            $append = array();

            foreach($result as &$product) {

                $product[$key] = array_shift($values);
                $copy = $product;
                foreach($values as $item) {
                    $copy[$key] = $item;
                    $append[] = $copy;
                }
                array_unshift($values, $product[$key]);
            }
            $result = array_merge($result, $append);
        }
    }

    return $result;
}

$data = array
(
    'machineAttribute' => array
    (
        'TTT 1000 S',
        'TTT 1100 S'
    ),

    'technicalAttribute' => array
    (
        'Certificate',
        'Software'
    ),

    'languageAttribute' => array
    (
        'English',
        'Spanish',
    )

);

$combos = cartesian($data);
$final_result = [];
foreach($combos as $combo){
    $final_result[] = implode('/',$combo);
}
print_r($final_result);

演示:https://3v4l.org/Zh6Ws

【讨论】:

  • 谢谢你。那是一些严重的数组操作。我测试了你的演示,它适用于数组值,但是当只有一个值时它会出错,但是我会尝试采用代码。谢谢你的好主意!
【解决方案4】:

这几乎可以解决你的问题。

$arr['machineAttribute'] = (array) $arr['machineAttribute'];
$arr['technicalAttribute'] = (array) $arr['technicalAttribute'];
$arr['languageAttribute'] = (array) $arr['languageAttribute'];

$machCount = count($arr['machineAttribute']);
$techCount = count($arr['technicalAttribute']);
$langCount = count($arr['languageAttribute']);

$attr = [];
for($i=0;$i<$machCount;$i++) {
    $attr[0] = $arr['machineAttribute'][$i] ?? "";
    for($j=0;$j<$techCount;$j++) {
        $attr[1] = $arr['technicalAttribute'][$j] ?? "";
        for($k=0;$k<$langCount;$k++) {
            $attr[2] = $arr['languageAttribute'][$k] ?? "";
            $pathArr[] = implode('/',array_filter($attr));
        }
    }
}

print_r($pathArr);

【讨论】:

  • 这也有效,很好的解决方案,感谢 Tamilvannan 的帮助!
【解决方案5】:

这也有效!

$results = [[]];

    foreach ($arrays as $index => $array) {
      $append = [];
      foreach ($results as $product) {
        foreach ($array as $item) {
            $product[$index] = $item;
            $append[] = $product;
        }
      }
      $results = $append;
    }
    print_r(array_map(function($arr){ return implode('/',$arr);},$results));

【讨论】:

    猜你喜欢
    • 2012-10-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-12-25
    • 2012-02-29
    相关资源
    最近更新 更多