1

内容: 2 つの配列のデータを比較し、その比較に基づいてステートメントを作成しようとしています。

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

Lets say on を探して配列をループして 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配列は異なって見えますが、u が言うように、ユーザーがそれらを設定します。そのため、「キッチン ライト」、「キッチン ライト」、およびユーザーが配列に追加したその他のもののすべてのケースをチェックする方法はありません。したがって、同じことに対して異なるトリガーを使用して、上記のように配列を埋めることができます。使いやすさが新しい の余分な構造を構成していると思います$sys。^^

更新:順序付けされていない入力を許可するように更新されました。1 つのコマンドで "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);

の 2 番目のパラメーターを使用して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 に答える