基于以下几个标准重新排序的数组的项目 [英] Re-order an array's items based on several criteria

查看:106
本文介绍了基于以下几个标准重新排序的数组的项目的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

每个人都问我发现这个问题太有挑战,希望有一个人在这里谁可以处理它。

我有一个与输入生成名片的程序了由用户(姓名,职务,地址等)。

我也有一个页面,用户可以配置信息将如何看待卡上:的http://截屏。 COM / T / 5j5CKAd0vi2l

这些配置使用,所以如果某些字段为空,那么其他领域可以移动到发生的空场的。

我们应该如何期望它的工作:
当检查了场,这意味着它可以移动。箭头指示它应该移动的位置。例如,名称应该向下移动,而标题应该向上移动。因此,如果没有在输入给定的名称,并有一个标题,则标题的上去取的名字的空的空间。

当未选中的场,这意味着它不能移动,和场不能把它的位置(或步骤超过它)。因此,举例来说,如果有一个名字,但没有标题,然后名称将下井拿冠军的地方,但不能进一步向下移动(即使办公电话是空的,所以会有一个空白名片上的空间)。

使用相同的结构实例中,如果用户没有输入一个移动和电子邮件,但输入的最后2个字段(地址1和市,州,邮编),那么这些最后2场会上升2场,及拿手机和电子邮件的地方。

比方说我的名片输入是:

 (选中,朝下)名称:丹
(选中,向上的)标题:
(未选中)办公室电话:
(选中,向上的)移动电话:
(选中,朝上)电子邮件:grwgwr@geffw.com
(选中,朝上)地址1:12 JAL
(选中,朝上)市,州,邮编:纽约,NY,12345

由此产生的renderValues​​数组,我需要看起来像:

 
    [0] =>
    [1] =>担
    [2] =>
    [3] => grwgwr@geffw.com
    [4] => 12日航
    [5] => NYC,NY,12345
    [6] =>

那不是我和我的code得到。你可能不需要它,它可能混淆甚至更多,但这里是我试图把创办至今:

 的foreach($ renderBlocksPropsByOrder为$ BLOCKID => $场){
    $方向= $场['blankSensitivityDirection'];    //注意:如果一个字段不为空敏感,它已被锁定    如果(修剪($ renderValues​​ [$ BLOCKID])==''&放大器;&放大器; $字段['isBlankSensitive'] =='1'){
        //如果($ renderBlocksPropsByOrder [$ BLOCKID + 1])
        //领域(S)围绕这个领域可以采取的立场
        //?如果该字段上面朝下和下面的字段朝上,到外地下来优先?
    }否则如果(修剪($ renderValues​​ [$ BLOCKID])==''和;&安培; $场['isBlankSensitive'] =='0'){
        上述本场//字段不能往下走过去,即使它是空的,但他们可以,直到他们达到这一切下去
        下面这个领域//领域上不去过去,即使它是空的,但直到他们达到它,他们都可以去了
        //这个领域将是一个空白空间场
    }否则如果(修剪($ renderValues​​ [$ BLOCKID])=!&放大器;&放大器; $字段['isBlankSensitive'] =='0'){
        //类似上述情况下,除了本领域将不会是一个空白空间
    }否则如果(修剪($ renderValues​​ [$ BLOCKID])=!&放大器;&放大器; $字段['isBlankSensitive'] =='1'){
        //此字段是否可以移动
        如果($方向==='下来'){
            //下面的检查领域将其移动到可用的最低点
            //(以下领域具有较高的指数)
            为($ I = $ BLOCKID + 1; $ I< $ numBlocks; $ I ++){
                如果(修剪($ renderValues​​ [$ i])!=''){
                    // prevent跨过具有值的字段
                    打破;
                }
                如果(修剪($ renderValues​​ [$ i])==''和;&安培; $ renderBlocksPropsByOrder [$ i] ['isBlankSensitive'] =='1'){
                    $ renderValues​​ [$ i] = $ renderValues​​ [$ BLOCKID];
                    $ renderValues​​ [$ BLOCKID] ='';
                    打破;
                }
            }
        }否则如果($方向==='起来'){
            //它上面的检查领域将其移动到可用的最高点
            //(场以上具有较低的指数)
            为($ I = $ BLOCKID - 1; $ I> = 0; $我 - ){
                如果(修剪($ renderValues​​ [$ i])!=''){
                    // prevent跨过具有值的字段
                    打破;
                }
                如果(修剪($ renderValues​​ [$ i])==''和;&安培; $ renderBlocksPropsByOrder [$ i] ['isBlankSensitive'] =='1'){
                    $ renderValues​​ [$ i] = $ renderValues​​ [$ BLOCKID];
                    $ renderValues​​ [$ BLOCKID] ='';
                    打破;
                }
            }
        }
    }}

阵列renderBlocksPropsByOrder有每个场的配置:

 
[0] =>排列
    (
        [BLOCKID] => 0
        [isBlankSensitive] => 1
        [blankSensitivityDirection] =>下
    )[1] =>排列
    (
        [BLOCKID] => 1
        [isBlankSensitive] => 1
        [blankSensitivityDirection] =>向上
    )[2] =>排列
    (
        [BLOCKID] => 2
        [isBlankSensitive] => 0
        [blankSensitivityDirection] => ''
    )[3] =>排列
    (
        [BLOCKID] => 3
        [isBlankSensitive] => 1
        [blankSensitivityDirection] =>向上
    )[4] =>排列
    (
        [BLOCKID] => 4
        [isBlankSensitive] => 1
        [blankSensitivityDirection] =>向上
    )[5] =>排列
    (
        [BLOCKID] =>五
        [isBlankSensitive] => 1
        [blankSensitivityDirection] =>向上
    )[6] =>排列
    (
        [BLOCKID] => 6
        [isBlankSensitive] => 1
        [blankSensitivityDirection] =>向上
    ))

RenderValues​​都有每个字段的值。初始renderValues​​排列如下:

 
    [0] =>担
    [1] =>
    [2] =>
    [3] =>
    [4] => grwgwr@geffw.com
    [5] => 12日航
    [6] => NYC,NY,12345

我已经花了上这真的任何帮助,可以帮助我往前走很长一段时间将是非常,非常AP preciated。

如果这种方式被证明是太复杂了,我会采取什么建议配置名片的替代,用户友好的方式。


解决方案

我希望它解决您的问题(发现这是一个有趣的案例,花这个上午的​​部)

编辑:只是重新制作的功能和模式,所以它会遍历预期,为了直到每个插槽都可以正确地整理一遍又一遍地查看整个模型。

  //卡型号
$卡=阵列(
    1 =>阵列(
        标签=>中名,
        canmove=>中下,
        值= GT;旦
        )
    2 =>阵列(
        标签=>中标题
        canmove=>中起来,
        值= gt;中
        )
    3 =>阵列(
        标签=>中办公室电话,
        canmove=>中N,
        值= gt;中
        )
    4 =>阵列(
        标签=>中的移动电话
        canmove=>中起来,
        值= gt;中
        )
    5 =>阵列(
        标签=>电子邮件,
        canmove=>中起来,
        值= GT;grwgwr@geffw.com
        )
    6 =>阵列(
        标签=>中地址1
        canmove=>中起来,
        值= gt;中日航12
        )
    7 =>阵列(
        标签=>中城市,州,邮编
        canmove=>中起来,
        值= GT;NYC,NY,12345
        )
);//渲染吧!
$ renderedCard = renderCard($卡);//测试
的foreach($ renderedCard为$关键=> $值){
    。回声[。$键]$值[标签]:。$值['值']< BR>中;
}//结构视图
回声< pre>中;
的print_r($ renderedCard);
回声< / pre>中;
//这个函数抵消空价值每个插槽,除非
//它的canmove'是'N',它可以完整保留
功能clearCard($卡){
    $ NEWCARD =阵列();
    的foreach($卡插槽$ = GT; $道具){
        $道具['值']!=''|| $道具['canmove'] =='N'?
            $ NEWCARD [$槽] = $卡[$槽]:
            $ NEWCARD [$槽] = NULL;
    }
    返回$ NEWCARD;
}//这个功能将使每个插槽占据空的,基于
//在canmove标准
功能renderCard($卡){
    $ cleanCard = clearCard($卡);
    $重构= 0;
    //超过cleanCard迭代执行冒泡排序
    而($重构<计数($ cleanCard)){
        的foreach($ cleanCard为$ SLOT => $道具){
            开关($道具['canmove']){
                //如果向上,而上行时隙是空的,
                //占据自己的位置和空本身下一
                案菜单:
                    //如果溢出卡阵列偏移,休息
                    如果($插槽-1< = 0)中断;
                    //如果上'值的空值,意味着它可以填补!
                    如果($ cleanCard [$插槽-1] == NULL){
                        $ cleanCard [$插槽-1] = $ cleanCard [$槽];
                        $ cleanCard [$槽] = NULL;
                    }
                    打破;
                //同'了',但检查向下场
                案降:
                    如果($插槽+ 1>计数($ cleanCard))打破;
                    如果($ cleanCard [$插槽+ 1] == NULL){
                        $ cleanCard [$插槽+ 1] = $ cleanCard [$槽];
                        $ cleanCard [$槽] = NULL;
                    }
                    打破;
            }
        }
        //递增重构循环,同时在cleanCard计数
        $重构++;
    }
    //完成后,返回渲染阵列
    返回$ cleanCard;
}

输出

1)继你的问题的型号:

  [1]:
[2]产品名称:丹
[3]办公室电话:
[4]电子邮件:grwgwr@geffw.com
[5]地址1:12 JAL
[6]市,省,邮编:纽约,NY,12345
[7]:

2)添加一个标题(CEO):

  [1]名称:丹
[2]标题:CEO
[3]办公室电话:
[4]电子邮件:grwgwr@geffw.com
[5]地址1:12 JAL
[6]市,省,邮编:纽约,NY,12345
[7]:

3)而现在,手机,以及:

  [1]名称:丹
[2]标题:CEO
[3]办公室电话:
[4]移动电话:55559999
[5]电子邮件:grwgwr@geffw.com
[6]地址1:12 JAL
[7]市,省,邮编:纽约,NY,12345

4)如果你有一个标题,而不是一个名称?让我们来看看:

  [1]标题:CEO
[2]:
[3]办公室电话:
[4]电子邮件:grwgwr@geffw.com
[5]地址1:12 JAL
[6]市,省,邮编:纽约,NY,12345
[7]:

5)让我们去掉地址1了,所以城市,省,邮编应该取代其位置:

  [1]标题:CEO
[2]:
[3]办公室电话:
[4]电子邮件:grwgwr@geffw.com
[5]市,省,邮编:纽约,NY,12345
[6]:
[7]:

6)设置电子邮件字段为 canmove 向下,以及地址1和市,省,邮编'与空值,因此邮件应在其一路向下移动:

  [1]标题:CEO
[2]:
[3]办公室电话:
[4]:
[5]:
[6]:
[7]电子邮件:grwgwr@geffw.com

随意进行其他检查,并给予反馈,我有一个伟大的时间做这个!

(删除有关索引和通知的问题previous答案前的修改,因为它不是这种情况了)

Everybody I asked found this problem too challenging, hopefully there is someone here who can handle it.

I have a program that generates business cards with inputs gave by a user (name, title, address etc.)

I also have a page where users can configure how the info will look on the card: http://screencast.com/t/5j5CKAd0vi2l

Those configurations are used so that if some fields are empty, then other fields can move to take place of the empty field.

How we should expect it to work: When a "field" is checked, it means that it can move. The arrow indicates the position where it should move. For example, name should move down, and title should move up. So if there is no name given in the input, and there is a title, then the title will go up and take the empty space of the name.

When a field is not checked, it means that it cannot move, and a field cannot take its position (or step over it). So for example if there is a name, but there is no title, then the name would go down to take the title's spot but couldn't go down any further (even if "Office tel" was empty, so there would be a blank space on the business card).

Using the same configurations example, if the user didn't input a mobile and email, but entered the last 2 fields (Address 1 and City, state, zip), then these last 2 fields would go up 2 fields, and take the places of mobile and email.

Let's say my business card inputs are:

(checked, pointing down) Name: Dan
(checked, pointing up) Title:
(unchecked) Office tel:
(checked, pointing up) Mobile tel:
(checked, pointing up) Email: grwgwr@geffw.com
(checked, pointing up) Address 1: 12 jal
(checked, pointing up) City, state, zip: NYC, NY, 12345

The resulting renderValues array that I need would look like:

(
    [0] =>
    [1] => Dan
    [2] => 
    [3] => grwgwr@geffw.com
    [4] => 12 jal
    [5] => NYC, NY, 12345
    [6] =>  
)

That's not what I'm getting with my code. You may not need it and it may confuse even more, but here's what I tried putting up so far:

foreach ($renderBlocksPropsByOrder as $blockID => $field) {
    $direction = $field['blankSensitivityDirection'];

    // note: if a field is not blank sensitive, it is locked

    if (trim($renderValues[$blockID]) == '' && $field['isBlankSensitive'] == '1') {
        // if ($renderBlocksPropsByOrder[$blockID + 1])
        // the field(s) around this field can take its position
        // ??? if the field above is pointing down and the field below is pointing up, give priority to the field down ???
    } else if (trim($renderValues[$blockID]) == '' && $field['isBlankSensitive'] == '0') {
        // fields above this field cannot go down past it even if it's empty, but they can all go down until they reach it
        // fields below this field cannot go up past it even if it's empty, but they can all go up until they reach it
        // this field will be a "blank" space field
    } else if (trim($renderValues[$blockID]) != '' && $field['isBlankSensitive'] == '0') {
        // similar as the above case, except this field won't be a blank space
    } else if (trim($renderValues[$blockID]) != '' && $field['isBlankSensitive'] == '1') {
        // this field should move if it can
        if ($direction === 'down') {
            // check fields below it to move it to the lowest available spot
            // (fields below have a higher index)
            for ($i = $blockID + 1; $i < $numBlocks; $i++) {
                if (trim($renderValues[$i]) != '') {
                    // prevent stepping over a field that has a value
                    break;
                }
                if (trim($renderValues[$i]) == '' && $renderBlocksPropsByOrder[$i]['isBlankSensitive'] == '1') {
                    $renderValues[$i] = $renderValues[$blockID];
                    $renderValues[$blockID] = ' ';
                    break;
                }
            }
        } else if ($direction === 'up') {
            // check fields above it to move it to the highest available spot
            // (fields above have a lower index)
            for ($i = $blockID - 1; $i >= 0; $i--) {
                if (trim($renderValues[$i]) != '') {
                    // prevent stepping over a field that has a value
                    break;
                }
                if (trim($renderValues[$i]) == '' && $renderBlocksPropsByOrder[$i]['isBlankSensitive'] == '1') {
                    $renderValues[$i] = $renderValues[$blockID];
                    $renderValues[$blockID] = ' ';
                    break;
                }
            }
        }
    }

}

The array renderBlocksPropsByOrder has the configuration of each field:

(
[0] => Array
    (
        [blockID] => 0
        [isBlankSensitive] => 1
        [blankSensitivityDirection] => down
    )

[1] => Array
    (
        [blockID] => 1
        [isBlankSensitive] => 1
        [blankSensitivityDirection] => up
    )

[2] => Array
    (
        [blockID] => 2
        [isBlankSensitive] => 0
        [blankSensitivityDirection] => ''
    )

[3] => Array
    (
        [blockID] => 3
        [isBlankSensitive] => 1
        [blankSensitivityDirection] => up
    )

[4] => Array
    (
        [blockID] => 4
        [isBlankSensitive] => 1
        [blankSensitivityDirection] => up
    )

[5] => Array
    (
        [blockID] => 5
        [isBlankSensitive] => 1
        [blankSensitivityDirection] => up
    )

[6] => Array
    (
        [blockID] => 6
        [isBlankSensitive] => 1
        [blankSensitivityDirection] => up
    )

)

RenderValues has the value of each field. Initial renderValues array looks like:

(
    [0] => Dan
    [1] => 
    [2] => 
    [3] => 
    [4] => grwgwr@geffw.com
    [5] => 12 jal
    [6] => NYC, NY, 12345
)

I've been spending a long time on this really any help that can help me go forward will be very, very appreciated.

If this way proves to be too complex, I'll take any suggestions for an alternative, user-friendly way of configuring the business cards.

解决方案

I hope it solves your problem (found it an interesting case and spent part of the morning on this)

EDIT: just re-made the functions and model, so it'll iterate as expected, in order to review the entire model over and over until each slot is sorted out correctly.

// Card Model
$card = array (
    1 => array(
        "label"=>"Name",
        "canmove"=>"down",
        "value"=>"Dan"
        ),
    2 => array(
        "label"=>"Title",
        "canmove"=>"up",
        "value"=>""
        ),
    3 => array(
        "label"=>"Office Tel",
        "canmove"=>"n",
        "value"=>""
        ),
    4 => array(
        "label"=>"Mobile Tel",
        "canmove"=>"up",
        "value"=>""
        ),
    5 => array(
        "label"=>"Email",
        "canmove"=>"up",
        "value"=>"grwgwr@geffw.com"
        ),
    6 => array(
        "label"=>"Address 1",
        "canmove"=>"up",
        "value"=>"12 jal"
        ),
    7 => array(
        "label"=>"City, State, Zip",
        "canmove"=>"up",
        "value"=>"NYC, NY, 12345"
        ),
);

// Render it!
$renderedCard = renderCard($card);

// Testing
foreach($renderedCard as $key=>$values) {
    echo "[".$key."] ".$values['label'].": ".$values['value']."<br>";
}

// Structural view
echo "<pre>";
print_r($renderedCard);
echo "</pre>";




// This function nullifies every slot with empty 'value', except if
// its 'canmove' is 'n', which may keep intact
function clearCard($card) {
    $newCard = array();
    foreach ($card as $slot=>$props) {
        $props['value'] != '' || $props['canmove'] == 'n' ?
            $newCard[$slot] = $card[$slot] :
            $newCard[$slot] = null;
    }
    return $newCard;
}

// This function will move each slot to occupy the empty ones, based
// on 'canmove' criteria
function renderCard($card) {
    $cleanCard = clearCard($card);
    $refactor = 0;
    // iterates over cleanCard to perform a 'bubble sort'
    while ($refactor < count($cleanCard)) {
        foreach ($cleanCard as $slot => $props) {
            switch ($props['canmove']) {
                // if 'up', and upward slot is empty,
                // occupy its place and null itself next
                case 'up':
                    // if it overflows the card array offset, breaks
                    if ($slot-1 <= 0) break;
                    // if upper 'value's null, means it can be filled!
                    if ($cleanCard[$slot-1] == null) {
                        $cleanCard[$slot-1] = $cleanCard[$slot];
                        $cleanCard[$slot] = null;
                    }
                    break;
                // same as 'up', but checking downward field
                case 'down':
                    if ($slot+1 > count($cleanCard)) break;
                    if ($cleanCard[$slot+1] == null) {
                        $cleanCard[$slot+1] = $cleanCard[$slot];
                        $cleanCard[$slot] = null;
                    }
                    break;
            }
        }
        // increment the refactor to loop while over cleanCard count
        $refactor++;
    }
    // when finished, returns the rendered array
    return $cleanCard;
}

OUTPUTS

1) Following the model on your question:

[1] :
[2] Name: Dan
[3] Office Tel:
[4] Email: grwgwr@geffw.com
[5] Address 1: 12 jal
[6] City, State, Zip: NYC, NY, 12345
[7] : 

2) Adding a "Title" (CEO):

[1] Name: Dan
[2] Title: CEO
[3] Office Tel:
[4] Email: grwgwr@geffw.com
[5] Address 1: 12 jal
[6] City, State, Zip: NYC, NY, 12345
[7] : 

3) And now, a "Mobile Phone" as well:

[1] Name: Dan
[2] Title: CEO
[3] Office Tel:
[4] Mobile Tel: 55559999
[5] Email: grwgwr@geffw.com
[6] Address 1: 12 jal
[7] City, State, Zip: NYC, NY, 12345

4) What if you have a "Title" but not a "Name"? Let's see:

[1] Title: CEO
[2] :
[3] Office Tel:
[4] Email: grwgwr@geffw.com
[5] Address 1: 12 jal
[6] City, State, Zip: NYC, NY, 12345
[7] : 

5) Let's remove the "Address 1" now, so "City, State, Zip" should take its place:

[1] Title: CEO
[2] :
[3] Office Tel:
[4] Email: grwgwr@geffw.com
[5] City, State, Zip: NYC, NY, 12345
[6] :
[7] :

6) [EDIT] Setting 'Email' field as canmove 'down', as well 'Address 1' and 'City, State, Zip' with empty values, so Email should move all its way down!:

[1] Title: CEO
[2] :
[3] Office Tel:
[4] :
[5] :
[6] :
[7] Email: grwgwr@geffw.com

Feel free to perform other tests and give a feedback, I had a great time doing this!

(Remove the former EDIT of the previous answer regarding issues on index and notices, since it isn't the case anymore)

这篇关于基于以下几个标准重新排序的数组的项目的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆