【问题标题】:Excluding a value from an array of data从数据数组中排除一个值
【发布时间】:2018-08-24 12:33:42
【问题描述】:

在我的in_array 中,我可以从$row->guestEmail 中排除特定术语吗?

例如,@example.comexample1.com$row->guestEmail 值的禁止子字符串。

这是我尝试过的:

foreach ($json->data as $row) {   
    if (!in_array($row->guestEmail, $emails)
            && date('Y-m-d', strtotime($row->endDate))== date('Y-m-d')) {
        $guests[] = array(
            'FirstName'      => $row->guestFirstName,
            'LastName'       => $row->guestLastName,
            'email'          => $row->guestEmail,
            'country'        => $row->guestCountry,
            'check-in_date'  => $row->startDate,
            'check-out_date' => $row->endDate,
        );
        $emails[] = $row->guestEmail;
    }
}

【问题讨论】:

  • 你的意思是你不想在数组中包含example和example1.com?
  • $emails 中有什么数据?
  • 它应该已经适用于您的实际代码!in_array($row->guestEmail, $emails)。您是否将要排除的电子邮件放在$emails array 中?
  • 您可以过滤以仅获取需要可迭代的数据。例如使用array_filter 之前使用foreach 到$json->data

标签: php object filtering blacklist


【解决方案1】:

如果您想要一个灵活的解决方案来扩展您的电子邮件黑名单,您可以使用 preg_match() 和基于您的不合格电子邮件数组的动态正则表达式模式。

\Q...\E 语法确保模式中的符号被处理literally。这与preg_quote() 的效果相同(没有函数调用)。

代码:(Demo)

$objs = (object)[
    'data' => [
        (object)['guestEmail' => 'bad@example.com'],
        (object)['guestEmail' => 'okay@goodstuff.com'],
        (object)['guestEmail' => 'nope@example1.com']
    ]
];

$blacklist = ['@example.com',  'example1.com'];
$regex = '~\Q' . implode('\E|\Q', $blacklist) . '\E~';

foreach ($objs->data as $row) {
    if (!preg_match($regex, $row->guestEmail)) {    
        $emails[] = $row->guestEmail;
    }
}

var_export($emails);

输出:

array (
  0 => 'okay@goodstuff.com',
)

如果您不喜欢正则表达式的想法,您可以为黑名单中的每个元素迭代调用stripos()stripos() 将比 substr_count() 执行得更好,因为 substr_count() 将继续读取字符串到最后(试图给出找到的字符串数量的准确计数)。 stripos() 将在找到第一次出现后立即停止——这是最佳代码设计。

代码:(Demo)

foreach ($objs->data as $row) {
    foreach ($blacklist as $forbidden_string) {
        if (stripos($row->guestEmail, $forbidden_string) !== false) {
            continue 2;
        }
    }
    $emails[] = $row->guestEmail;
}
// same result as first snippet

【讨论】:

  • @Jess in_array() 在您想要进行部分匹配时不是一个很好的调用函数。要使此解决方案可扩展,您需要使用动态正则表达式模式或迭代 stripos() 调用来阻止某些域。
【解决方案2】:

你可以这样做:

if (!in_array($row->guestEmail, $emails)
            && date('Y-m-d', strtotime($row->endDate))== date('Y-m-d') && substr_count($row->guestEmail, 'example.com') < '1' && substr_count($row->guestEmail, 'example1.com') < '1') {

//your code

希望对你有帮助

【讨论】:

  • 问问自己为什么您选择了substr_count(),以及是否可以找到更简单/更轻松的函数来调用。还要问问自己in_array() 条件有多好。另一个考虑因素是可维护性——您是否希望 OP 继续为黑名单中的每个值写出 substr_count() 调用?
  • 好吧,如果我们只想删除特定的邮件,比如 abc@example.com,那很容易。只需使用 $excludeArray 方法。但是如果我们想基于 example.com 或 example1.com 隐藏,我们必须在每封邮件中检查这些字符串。这就是我的背景。
  • 你好像不知道更好的方法,我会尽快发布。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-02-19
  • 2018-12-19
  • 1970-01-01
  • 2015-12-19
  • 1970-01-01
相关资源
最近更新 更多