Arrays 更改关联阵列中关键点的位置

Arrays 更改关联阵列中关键点的位置,arrays,sorting,associative-array,key,Arrays,Sorting,Associative Array,Key,我正在创建一个表单生成器,它接受一些配置数组并构建html。例如:我有以下关联数组来描述字段的显示方式: $fieldSpec = array( 'nome' => array( 'label' => 'Nome', ), 'descricao' => array( 'label' => 'Descrição', ), 'preco' => array( 'label' =>

我正在创建一个表单生成器,它接受一些配置数组并构建html。例如:我有以下关联数组来描述字段的显示方式:

$fieldSpec = array(
    'nome' => array(
        'label' => 'Nome',
    ),
    'descricao' => array(
        'label' => 'Descrição',
    ),
    'preco' => array(
        'label' => 'Preço',
    ),
);
问题:我想轻松地重新定位关键点,而不必一直剪切和粘贴。所以我想问问某人是否知道一个函数或类来管理它;必须是这样的:

ChangeKeyPosition(&$fieldSpec,'preco','up',2);

// that would produce:
$fieldSpec = array(
    'preco' => array( # <- notice this element came 2 levels up
            'label' => 'Preço',
        ),
    'nome' => array(
        'label' => 'Nome',
    ),
    'descricao' => array(
        'label' => 'Descrição',
    ),

);
$man = new KeyPositionManager(&$fieldSpec);
$man->up('preco',2);
$man->after('nome','descricao');
etc...
我甚至更愿意像这样使用包装数组引用的对象:

ChangeKeyPosition(&$fieldSpec,'preco','up',2);

// that would produce:
$fieldSpec = array(
    'preco' => array( # <- notice this element came 2 levels up
            'label' => 'Preço',
        ),
    'nome' => array(
        'label' => 'Nome',
    ),
    'descricao' => array(
        'label' => 'Descrição',
    ),

);
$man = new KeyPositionManager(&$fieldSpec);
$man->up('preco',2);
$man->after('nome','descricao');
etc...
更新: 所以我最终自己创建了一组函数来完成我所要求的。它可能对其他人有用,也可能不有用:

function array_key_move(&$oarr, $key, $move)
{
    $keys = array_keys($oarr);
    $opos = array_search($key,$keys);
    if($opos===false) return;
    $npos = $opos + $move + ($move > 0 ? +0.1 : -0.1);
    $keys["$npos"] = $key;
    unset($keys[$opos]);
    ksort($keys);
    foreach($keys as $k)
    {
        $narr[$k] = $oarr[$k];
    }
    $oarr = $narr;
}

function array_key_set_at(&$oarr, $tkey, $nkey, $nval, $before = true)
{
    $tpos = array_search($tkey,array_keys($oarr));
    if($tpos===false) return;
    $narr = array();
    $i = 0;
    foreach($oarr as $k => $v)
    {
        if($tpos==$i)
        {
            $before AND $narr[$nkey] = $nval;
            $narr[$k] = $v;
            $before OR $narr[$nkey] = $nval;
        } else $narr[$k] = $v;
        $i++;
    }
    $oarr = $narr;
}

function array_key_move_before(&$oarr, $key_element, $key_target)
{
    $copy_element = $oarr[$key_element];
    unset($oarr[$key_element]);
    array_key_set_at($oarr, $key_target, $key_element, $copy_element, TRUE);
}

function array_key_move_after(&$oarr, $key_element, $key_target)
{
    $copy_element = $oarr[$key_element];
    unset($oarr[$key_element]);
    array_key_set_at($oarr, $key_target, $key_element, $copy_element, FALSE);
}

function array_key_move_start(&$oarr, $key)
{
    if(!isset($oarr[$key])) return;
    $narr[$key] = $oarr[$key];
    foreach($oarr as $k => $v)
    {
        $k!=$key AND $narr[$k]=$v;
    }
    $oarr = $narr;
}

function array_key_move_end(&$oarr, $key)
{
    if(!isset($oarr[$key])) return;
    foreach($oarr as $k => $v)
    {
        $k!=$key AND $narr[$k]=$v;
    }
    $narr[$key] = $oarr[$key];
    $oarr = $narr;
}

function array_key_set_start(&$oarr,$key,$val)
{
    $oarr[$key] = $val;
    array_key_move_start($oarr,$key);
}


function array_key_set_end(&$oarr,$key,$val)
{
    $oarr[$key]=$val; # :-)
}

function array_key_switch2(&$oarr,$ka,$kb)
{
    $keys = array_keys($oarr);
    if(($kapos = array_search($ka, $keys))===false) return;
    if(($kbpos = array_search($kb, $keys))===false) return;
    $i = 0;
    foreach($oarr as $k => $v)
    {
        if($i==$kapos)
            $narr[$kb] = $oarr[$ka];
        elseif($i==$kbpos)
            $narr[$ka] = $oarr[$kb];
        else
            $narr[$k] = $v;
        $i++;
    }
    $oarr = $narr;
}
示例:

数组键移动($arr,'f',-3)

Array
(
    [a] => 1
    [b] => 2
    [f] => 6 # <- "f"
    [c] => 3 #
    [d] => 4 #
    [e] => 5
)
Array
(
    [b] => 2 #
    [a] => 1 # <- "a"
    [f] => 6
    [c] => 3
    [d] => 4
    [e] => 5
)
Array
(
    [a] => 1
    [f] => 6
    [c] => 3
    [d] => 4
    [e] => 5
    [b] => 2 # <- "b" after "e"
)
Array
(
    [b] => 2 # <- "b" at start
    [a] => 1
    [f] => 6
    [c] => 3
    [d] => 4
    [e] => 5
)
Array
(
    [r] => 7 # <- prepended
    [b] => 2
    [a] => 1
    [f] => 6
    [c] => 3
    [d] => 4
    [e] => 5
)
Array
(
    [e] => 7 # <-
    [b] => 2
    [a] => 1
    [f] => 6
    [c] => 3
    [d] => 4
    [r] => 5 # <-
)
最后

数组键开关2($arr,'r','e')

Array
(
    [a] => 1
    [b] => 2
    [f] => 6 # <- "f"
    [c] => 3 #
    [d] => 4 #
    [e] => 5
)
Array
(
    [b] => 2 #
    [a] => 1 # <- "a"
    [f] => 6
    [c] => 3
    [d] => 4
    [e] => 5
)
Array
(
    [a] => 1
    [f] => 6
    [c] => 3
    [d] => 4
    [e] => 5
    [b] => 2 # <- "b" after "e"
)
Array
(
    [b] => 2 # <- "b" at start
    [a] => 1
    [f] => 6
    [c] => 3
    [d] => 4
    [e] => 5
)
Array
(
    [r] => 7 # <- prepended
    [b] => 2
    [a] => 1
    [f] => 6
    [c] => 3
    [d] => 4
    [e] => 5
)
Array
(
    [e] => 7 # <-
    [b] => 2
    [a] => 1
    [f] => 6
    [c] => 3
    [d] => 4
    [r] => 5 # <-
)
数组
(
[e] =>7#2
[a] =>1
[f] =>6
[c] =>3
[d] =>4

[r] =>5#只是一个旁注:如果您在设计中依赖于assoc数组中的键顺序,那么您就做错了。无论如何,请查看ksort()函数。这不是您所要求的,但它会使您的操作保持一致。我曾想过使用一个单独的数组来告诉我显示元素的顺序,比如$order=array('preco','descripao',等等。)。如果未给出$order参数,则生成器将选择默认顺序。这是更好的设计选择吗?在PHP中,键的顺序是保留的,不是吗,即键的顺序是它们添加到数组中的顺序,除非以某种方式操作键(例如ksort)?这就是说,如果你想开始扰乱键顺序,不如像上面描述的那样维护第二个具有严格数字索引的数组。在数组中移动值肯定比在键中移动更容易。此外,你不能真正移动assoc数组中键的顺序,是吗?你必须构建一个新数组并插入它ems以新的顺序一个接一个。我可能错了,tho…@fabio:最好的方法是将一对数组封装在一个类中,一个包含实际数据,另一个包含键顺序,并提供方法来操作键顺序,同时为了方便起见,还可以证明迭代器接口(可能还有其他接口)。