1

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

$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' on or off '0'),(单独的下一个列表...)

我熟悉array_intersect。

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

我确定我可以遍历数组寻找让我们说并用 256 或 0 替换它,但我遇到了思考如何执行以下操作的问题:

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

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

谢谢,JT

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

4

2 回答 2

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”|”实例

于 2013-09-11T18:46:26.407 回答
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 数组的正确键。

在这个小提琴中看到它的实际效果

编辑

用于管理不同格式的不同输入(不更改 $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);
}

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

于 2013-09-11T15:39:09.700 回答