更改关联数组中键的位置

发布于 2024-11-17 00:10:07 字数 5598 浏览 2 评论 0原文

我正在创建一个表单生成器,它需要一些配置数组并构建 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',
    ),

);

我想要拥有的其他可能的功能:

ChangeKeyPosition(&$fieldSpec,'descricao','down',1);
// send element "preco" to the top
ChangeKeyPosition(&$fieldSpec,'preco','top');
// send element "nome" to the end of the array
ChangeKeyPosition(&$fieldSpec,'nome','bottom');
// place "nome" before "preco"
ChangeKeyPosition(&$fieldSpec,'nome','before','preco');
// place "nome" after "descricao"
ChangeKeyPosition(&$fieldSpec,'nome','after','descricao');
// place "preco" between "nome" and "descricao"
ChangeKeyPosition(&$fieldSpec,'preco','between',array('nome','descricao'));

我什至更喜欢使用包装数组引用的对象,如下所示:

$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;
}

示例:

array_key_move($arr,'f',-3);

Array
(
    [a] => 1
    [b] => 2
    [f] => 6 # <- "f"
    [c] => 3 #
    [d] => 4 #
    [e] => 5
)

array_key_move($arr,'a ',+1);

Array
(
    [b] => 2 #
    [a] => 1 # <- "a"
    [f] => 6
    [c] => 3
    [d] => 4
    [e] => 5
)

array_key_move_after($arr,'b','e');

Array
(
    [a] => 1
    [f] => 6
    [c] => 3
    [d] => 4
    [e] => 5
    [b] => 2 # <- "b" after "e"
)

array_key_move_start($arr,'b');

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

array_key_set_start($arr,'r',7);

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

*obs:以上不是 array_unshift 的别名 例如: array_unshift($arr,array('r'=>7)); 会产生:*

Array
(
    [0] => Array
        (
            [r] => 7
        )

    [b] => 2
    [a] => 1
    [f] => 6
    [c] => 3
    [d] => 4
    [e] => 5
)

最后

array_key_switch2($arr,'r','e');

Array
(
    [e] => 7 # <-
    [b] => 2
    [a] => 1
    [f] => 6
    [c] => 3
    [d] => 4
    [r] => 5 # <-
)

I'm creating a form generator that takes some configuration arrays and build the html. Ex: I have the following associative array to describe how the fields should be displayed:

$fieldSpec = array(
    'nome' => array(
        'label' => 'Nome',
    ),
    'descricao' => array(
        'label' => 'Descrição',
    ),
    'preco' => array(
        'label' => 'Preço',
    ),
);

problem: I want to reposition the keys easily without having to be cutting & pasting all the time. So i thought to ask somebody if they know a function or class to manage this; it would have to be something like this:

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',
    ),

);

other possible features I would like to have:

ChangeKeyPosition(&$fieldSpec,'descricao','down',1);
// send element "preco" to the top
ChangeKeyPosition(&$fieldSpec,'preco','top');
// send element "nome" to the end of the array
ChangeKeyPosition(&$fieldSpec,'nome','bottom');
// place "nome" before "preco"
ChangeKeyPosition(&$fieldSpec,'nome','before','preco');
// place "nome" after "descricao"
ChangeKeyPosition(&$fieldSpec,'nome','after','descricao');
// place "preco" between "nome" and "descricao"
ChangeKeyPosition(&$fieldSpec,'preco','between',array('nome','descricao'));

I would even prefer to work with an object wrapping the array reference like this:

$man = new KeyPositionManager(&$fieldSpec);
$man->up('preco',2);
$man->after('nome','descricao');
etc...

Update:
So I ended up creating a set of functions myself to do just what I was asking for. It may or may not be useful for somebody else:

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;
}

Examples:

array_key_move($arr,'f',-3);

Array
(
    [a] => 1
    [b] => 2
    [f] => 6 # <- "f"
    [c] => 3 #
    [d] => 4 #
    [e] => 5
)

array_key_move($arr,'a',+1);

Array
(
    [b] => 2 #
    [a] => 1 # <- "a"
    [f] => 6
    [c] => 3
    [d] => 4
    [e] => 5
)

array_key_move_after($arr,'b','e');

Array
(
    [a] => 1
    [f] => 6
    [c] => 3
    [d] => 4
    [e] => 5
    [b] => 2 # <- "b" after "e"
)

array_key_move_start($arr,'b');

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

array_key_set_start($arr,'r',7);

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

*obs: the above is not an alias to array_unshift
ex: array_unshift($arr,array('r'=>7));
would produce:*

Array
(
    [0] => Array
        (
            [r] => 7
        )

    [b] => 2
    [a] => 1
    [f] => 6
    [c] => 3
    [d] => 4
    [e] => 5
)

and finally

array_key_switch2($arr,'r','e');

Array
(
    [e] => 7 # <-
    [b] => 2
    [a] => 1
    [f] => 6
    [c] => 3
    [d] => 4
    [r] => 5 # <-
)

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

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

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文