根据几个条件重新排序数组的项目

时间:2015-08-13 13:55:21

标签: php arrays sorting

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

我有一个程序可以生成带有用户输入的名片(名称,标题,地址等)。

我还有一个页面,用户可以在其中配置信息在卡片上的显示方式:CorHttpd Cordova Plugin

使用这些配置,以便如果某些字段为空,则其他字段可以移动以取代空字段。

我们应该如何期待它的运作: 选中“字段”时,表示它可以移动。箭头表示它应该移动的位置。例如,名称应向下移动,标题应向上移动。因此,如果输入中没有给出名称,并且有标题,那么标题将会上升并占据名称的空白区域。

如果未选中某个字段,则表示它无法移动,并且字段无法占据其位置(或跨越它)。因此,例如,如果有一个名称,但没有标题,那么名称将下去取得标题的位置,但不能再进一步下降(即使“办公室电话”是空的,所以会有一个空白名片上的空间。)

使用相同的配置示例,如果用户没有输入移动电话和电子邮件,但输入了最后2个字段(地址1和城市,州,邮政编码),则最后2个字段将上升2个字段,拿走手机和电子邮件的地方。

假设我的名片输入是:

(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

我需要的结果renderValues数组如下所示:

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

这不是我的代码所得到的。你可能不需要它,它可能会更加混乱,但这是我到目前为止所尝试的内容:

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

}

数组renderBlocksPropsByOrder具有每个字段的配置:

(
[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具有每个字段的值。初始renderValues数组看起来像:

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

我已经花了很长时间在这上面,任何可以帮助我前进的帮助都会非常非常感激。

如果这种方式过于复杂,我会采取任何建议,以另一种用户友好的方式配置名片。

1 个答案:

答案 0 :(得分:0)

我希望它能解决你的问题(发现这是一个有趣的案例,早上花了一部分时间)

编辑:只是重新制作了函数和模型,因此它会按预期迭代,以便反复查看整个模型,直到每个插槽都正确排序。

// 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)关注你问题的模型:

[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)添加“标题”(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)现在,还有一部“移动电话”:

[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)如果您有“标题”但没有“名称”怎么办?我们来看看:

[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)现在让我们删除“地址1”,因此“城市,州,邮编”应该取而代之:

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

6)[编辑]将“电子邮件”字段设置为canmove“向下”,以及“地址1”和“城市,州,邮编”设置为空值,因此电子邮件应将其全部移动下来!:

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

随意进行其他测试并给出反馈,我很开心这样做!

(删除前一个关于索引和通知问题的答案的前编辑,因为不再是这种情况了)