检测数组中元素的移动位置

时间:2015-11-16 00:23:19

标签: php arrays

我必须能够使用新旧数据检测“公会”(如活动Feed)中的所有更改。数据以这种方式呈现为数组:

{"GUILDMASTER":["foo"],"OFFICER":["bar","baz"],"MEMBER":["foobar","foobaz"]}

我需要检测,例如,"bar"是否从当前等级向下移动一个(到"MEMBER"),它将输出如下所示的数组:

[{"user":"bar","was_found_in":"OFFICER","now_found_in":"MEMBER"}]

我目前拥有的内容,仅在下方检测会员是否已加入左侧,是否有任何方法可以扩展此功能以实现我的目标?

function compareThem($a, $b) {
    $flat_new = call_user_func_array('array_merge', $a);
    $flat_old = call_user_func_array('array_merge', $b);
    $rm = array();

    if($flat_new != $flat_old) {
        $new_old = array_diff($flat_new, $flat_old);
        $old_new = array_diff($flat_old, $flat_new);
        $diff = array_merge($new_old, $old_new);
        foreach ($diff as $key => $value) {
            if(in_array($value, $flat_new) && !in_array($value, $flat_old)) {
                $rm[] = array("new"=>true, "left"=>false, "user"=>$value);
            } else if(in_array($value, $flat_old) && !in_array($value, $flat_new)) {
                $rm[] = array("new"=>false, "left"=>true, "user"=>$value);
            }
        }
    }
    return $rm;
}
$new = array("GUILDMASTER" => array("foo"), "OFFICER" => array("bar", "baz"), "MEMBER" => array("foobar", "foobaz"));
$old = array("GUILDMASTER" => array("foo"), "OFFICER" => array("bar", "baz"), "MEMBER" => array("foobar"));
compareThem($new,$old) // will output [{"new":true,"left":false,"user":"foobaz"}]

1 个答案:

答案 0 :(得分:0)

你可以这样做。它检测添加,删除和修改:

// your array before the change
$before = ["GUILDMASTER" => ["foo"], "OFFICER" => ["bar","baz"], "MEMBER" => ["foobar","foobaz"]];

// your array after the change (foo was moved from GUILDMASTER to OFFICER)
$after = ["GUILDMASTER" => [], "OFFICER" => ["bar","baz", "foo"], "MEMBER" => ["foobar","foobaz"]];

// create lookup table to check the position a person previously held
$positions_before = [];
foreach($before as $position => $people) {
  foreach($people as $person) {
    $positions_before[$person] = $position;
  }
}

// scan new positions...
$changes = [];
foreach($after as $position => $people) {
  foreach($people as $person) {
    // track when a new person is added (they wont be in the table)
    if(!isset($positions_before[$person])) {
      $changes[] = ["user" => $person, "was_found_in" => "DIDNT_EXIST", "now_found_in" => $position];
    // track when a change is detected (different value than table)
    }elseif($positions_before[$person] != $position) {
      $changes[] = ["user" => $person, "was_found_in" => $positions_before[$person], "now_found_in" => $position];
    }
    // remove this person from the table after parsing them
    unset($positions_before[$person]);
  }
}

// anyone left in the lookup table is in $before and $after
// so track that they were removed/fired
foreach($positions_before as $person => $position) {
  $changes[] = ["user" => $person, "was_found_in" => $position, "now_found_in" => "REMOVED"];
}

print_r($changes);

输出[user] => foo [was_found_in] => GUILDMASTER [now_found_in] => OFFICER

相关问题