比较两个数组并创建一个语句

时间:2013-09-11 15:22:10

标签: php regex arrays sorting

什么:我正在尝试比较两个数组中的数据,并根据比较编写一个语句,

$sys = array("1"=>'kitchen lights', "2"=>'living lights', "3"=>'living fan');

$input = array('off kitchen lights','on living fan');

注意:输入可以按任何顺序排列! :-/ 有任何想法吗 比较这些以允许我更改数据库中的状态并写入更改日志。

sys数组键在这里也很重要。

我正在拍摄以下结果:

$write = '1:0,2:256';// means off kitchen lights and on living fan

写入被分成这样的位:

($ sys数组键号):('256'开启或关闭'0'),(单独的下一个清单......)

我熟悉array_intersect。

 $wordin = explode(" ", $input);
 $wordsys = explode(" ", $sys);
 $result = array_intersect($wordin, $wordsys);

我确定我可以遍历数组寻找让我们说出来并用256或0替换它但我正在考虑如何执行以下操作的问题:

处理灯光与灯光之类的变化...我需要它们与此相同...... 保留sys数组键号

注意:我不确定“更简单”的方法,但我会收回任何反馈!

谢谢, JT

更多信息:用户键入字符串。我从字符串中拉出所有细节并到达输入数组。 sys是用户设置的预定义数据库。

2 个答案:

答案 0 :(得分:2)

要为同一事物设置不同的触发器,您可以执行类似的操作(允许您轻松添加更多触发器)。你也可以在触发器中放置一些正则表达式并对它们进行评估,但你可以自己解决这个问题;)

<?php

define('SWITCHED_ON', 256);
define('SWITCHED_OFF', 0);

$sys = array(
    '1' => array(
        'name' => 'Kitchen Lights',
        'triggers' => array(
            'kitchen light',
            'kitchen lights',
        ),
    ),
    '2' => array(
        'name' => 'Living Lights',
        'triggers' => array(
            'living lights',
            'lights in living room',
            'light in living room',
        ),
    ),
    '3' => array(
        'name' => 'Living Fan',
        'triggers' => array(
            'living fan',
            'fan in living room',
        ),
    ),
);

$input = array('off kitchen lights','on living fan');
$output = array();
foreach ( $input as $command ) {

    // split command at first whitespace
    // $command_array = preg_split('%\s+%', $command, 2);
    // update to allow input like $input = array('kitchen off lights','living fan on');
    $split = preg_split('%\s+%', $command);
    $input_switch = false;
    $input_trigger = array();
    foreach ( $split as $part ) {
        if ( $input_switch === false ) {
            switch ( $part ) {
                case 'on': $input_switch = SWITCHED_ON; break;
                case 'off': $input_switch = SWITCHED_OFF; break;
                default: $input_trigger[] = $part; break;
            }
        } else {
            $input_trigger[] = $part;
        }
    }
    if ( $input_switch === false || empty($input_trigger) ) {
            continue;
    }

    $input_trigger = implode(' ', $input_trigger);


    // insert check if command is valid (for example contains only spaces and alphanumerics.. etc..)
    // ...

    foreach ( $sys as $syskey => $conf ) {
        foreach ( $conf['triggers'] as $trigger ) {
            if ( $trigger == $input_trigger ) {
                $output[] = $syskey.':'.$input_switch;
                continue 3; // continue outer foreach
            }
        }
    }

    // if you arrive here, the command was not found in sys

}
$output = implode(',', $output);
echo $output;

PS:$sys数组看起来不同,但正如你所说,用户设置它们。所以没有办法检查“厨房灯”,“厨房灯”的所有情况,以及用户放入阵列的其他东西。所以他们可以像上面一样填充数组,同样的东西有不同的触发器。我认为易用性构成了新$sys的额外结构。 ^^

更新:已更新以允许无序输入。我认为无序输入很难处理,如果你不能确定在一个命令中找到了多少个“off”或“on”这个单词的实例。如果有更多实例,您将无法确定哪个“开”或“关”是正确的实例。可能有一条规则......就像“on”或“off”的第一个实例是“我们将使用的”或其他东西。上面的代码将使用该规则。因此,如果你输入一个命令,如“厨房关闭灯关闭”,它将导致试图关闭触发“厨房灯关闭”的东西。另一种可能的方法是,如果有更多“on”|“off”实例,则拒绝该命令。或者剪切“on”|“off”的多个实例。

答案 1 :(得分:1)

试试这个:

$values = array();
foreach ($input as $i) {
    $parts = explode(' ', $i);
    // first word: 'on' || 'off'
    $val = array_shift($parts); 
    // attach the remaining words again to form the key
    $key = implode(' ', $parts);
    // get the index of the $key value in $sys array
    // and concat 0 or 156 depending on $val
    $values[] = array_shift(array_keys($sys, $key)).':'.($val == 'on' ? 256: 0);
}
$write = implode(';', $values);

使用array_keys的第二个参数来获取$ sys数组的正确键。

this fiddle

中查看此操作

修改

用于管理不同格式的不同输入(不更改$ sys数组):

$alts = array(
    'kitchen lights' => array(
        'kitchen lights', 'kitchen lights', 'lights in kitchen', 'light in kitchen'
    ),
    'living fan' => array(
        'living fan', 'living fans', 'fans in living', 'fan in living'
    ),
);
foreach ($input as $i) {
    $i = strtolower($i); // make sure we have all lower caps
    // check if on in in the start or beginning of the input
    $flag = substr($i, 0, 2) === 'on' || strpos($i, strlen($i)-1, 2) === 'on';
    // remove on and off from the string, trim whitespace
    $search = trim(str_replace(array('on', 'off'), '', $i));
    // search for the resulting string in any of the alt arrays
    $foundSysKey = false;
    foreach ($alts as $sysKey => $alt) {
        if (in_array($search, $alt)) {
            $foundSysKey = $sysKey;
            break;
        }
    }
    // did not find it? continue to the next one
    if ($foundSysKey === false) {
        echo 'invalid key: '.$search;
        continue;
    }
    // now you have the info we need and can precede as in the previous example
    $values[] = array_shift(array_keys($sys, $foundSysKey)).':'.($flag ? 256: 0);
}

我尝试保存更新的小提琴,但网站似乎有一些问题......虽然确实有效。