我有阵列
$rows = [
['k'=>1, 'dop1'=>'take', 'dop2' => 'a', 'dat' => '25-11-2016'],
['k'=>2, 'dop1'=>'make', 'dop2' => 'b', 'dat' => '26-11-2016'],
['k'=>3, 'dop1'=>'sake', 'dop2' => 'c', 'dat' => '27-11-2016'],
['k'=>4, 'dop1'=>'bake', 'dop2' => 'd', 'dat' => '28-11-2016'],
['k'=>5, 'dop1'=>'dake', 'dop2' => 'e', 'dat' => '29-11-2016'],
['k'=>6, 'dop1'=>'jake', 'dop2' => 'f', 'dat' => '30-11-2016'],
['k'=>7, 'dop1'=>'ake', 'dop2' => 'g', 'dat' => '24-11-2016']
];
和另一个用于过滤的数组
$filters = [
['dat', '=', '27-11-2016'],
['dop1', '=', "bake"],
['dop1', '=', "sake"],
['dop1', '=', "take"],
];
如果重复数组过滤器的第一个元素,它们之间将是OR
表达式,否则将是AND
表达式。
所以此处的结果必须为['k'=>3, 'dop1'=>'sake', 'dop2' => 'c', 'dat' => '27-11-2016']
,因为过滤器数组中存在'dat' => '27-11-2016'
,而'dop1'=>'sake''dop1'=>'sake'
也存在。你能帮帮我吗?
UPDATE 这是我的代码示例,但在注释时会出现问题。
$dop = ['dop1', 'dop2', 'dop3', 'dop4'];
$result = [];
foreach ($rows as $row) {
foreach ($filters as $filter) {
if(in_array($filter[0], $dop)){
$new_filter = [];
$f = explode("\n", $filter[2]);
foreach ($f as $item) {
array_push($new_filter, [$filter[0], $filter[1], $item]);
}
if(count($result) == 0){
foreach ($new_filter as $new) {
if($row[$new[0]] == $new[2]){
array_push($result, ['r' => $row, 'filter' => $new, 'validity' => 'valid']);
}
}
} else {
foreach ($new_filter as $new) {
for($i=0;$i<count($result);$i++){
if($result[$i]['filter'][0] == $new[0] && $result[$i]['filter'][1] == $new[1] && $result[$i]['filter'][2] != $new[2]){
//array_push($result, ['r' => $row, 'filter' => $new, 'validity' => 'valid']);
}
}
}
$invalid = 1;
$id = 0;
foreach ($new_filter as $new) {
for($i=0;$i<count($result);$i++){
if($result[$i]['r'][$new[0]] == $new[2]){
$invalid = 0;
$id = $i;
break 2;
}
}
}
if($invalid == 1){
$result[$id]['validity'] = 'invalid';
}
}
} elseif($filter[0] == 'dat') {
if(count($result) == 0){
if($row[$filter[0]] == $filter[2]){
array_push($result, ['r' => $row, 'filter' => $filter, 'validity' => 'valid']);
}
} else {
if($row[$filter[0]] == $filter[2]){
for($i=0;$i<count($result);$i++){
if($result[$i]['r'][$filter[0]] != $filter[2]){
$result[$i]['validity'] = 'invalid';
}
}
}
}
}
}
}
$c = 0;
foreach ($result as $r) {
if($r['validity'] == 'valid'){
$c++;
}
}
echo $c;
答案 0 :(得分:0)
因此,如果不为您编写代码,请查看PHP's array_filter()
您需要的伪代码如下所示:
var_dump(array_filter($rows, function($row) {
global $filtered;
$match = 0;
foreach ($filtered as $index=>$filter) {
// run code here to determine if this is an OR or AND and apply matching to the $row
// $row will be like ['k'=>1, 'dop1'=>'take', 'dop2' => 'a', 'dat' => '25-11-2016'],
// match based on the index of your $filtered ($index===0 AND, otherwise OR)
}
return $match;
});
答案 1 :(得分:0)
为你做了一些工作,不好的是我的方式需要一个grep "command[USEREGEX]" | wc -l
这可能是危险的,这取决于你在价值观中的字符串......
eval
在这里工作正常。
在线观看:http://sandbox.onlinephpfunctions.com/code/185658700006fe913e6592a7fc51d4cce0db6a68
首先,我要构建一系列可以使用的过滤器,然后将其应用于所有行。就这么简单:p
希望它有所帮助:)
编辑:
重建该函数的一些糟糕部分,删除$rows = [
['k'=>1, 'dop1'=>'take', 'dop2' => 'a', 'dat' => '25-11-2016'],
['k'=>2, 'dop1'=>'make', 'dop2' => 'b', 'dat' => '26-11-2016'],
['k'=>3, 'dop1'=>'sake', 'dop2' => 'c', 'dat' => '27-11-2016'],
['k'=>4, 'dop1'=>'bake', 'dop2' => 'd', 'dat' => '28-11-2016'],
['k'=>5, 'dop1'=>'dake', 'dop2' => 'e', 'dat' => '29-11-2016'],
['k'=>6, 'dop1'=>'jake', 'dop2' => 'f', 'dat' => '30-11-2016'],
['k'=>7, 'dop1'=>'ake', 'dop2' => 'g', 'dat' => '24-11-2016']
];
$filters = [
['dat', '=', '27-11-2016'],
['dop1', '=', "bake"],
['dop1', '=', "sake"],
['dop1', '=', "take"],
];
function marrfilter($filters_arr, $rows)
{
/*
* Building filters to eval
*/
$buildFilter = function($key, $op, $val)
{
switch($op)
{
case '=':
$op = '==';
break;
case '==':
case '===':
case '!=':
case '!==':
case '>':
case '>=':
case '<':
case '<=':
break;
default:
throw new Exception('Unknown operand');
}
$val = addslashes($val);
return '$val ' . $op . " '" . $val . "'";
};
$filters = array();
foreach($filters_arr as $k => $v)
{
list($key, $op, $val) = $v;
if( !isset($filters[$key]) )
{
$filters[$key] = $buildFilter($key, $op, $val);
}
else
{
if( !is_array($filters[$key]) )
{
$filters[$key] = array($filters[$key]);
}
$filters[$key][] = $buildFilter($key, $op, $val);
}
}
/*
* Filter function
*/
$applyFilter = function($row, $fk, $fv)
{
if( !array_key_exists($fk, $row) )
{
return false;
}
$val = $row[$fk];
if( is_array($fv) )
{
$test = false;
foreach($fv as $ft)
{
eval('$test = (' . $ft . ');');
if( $test ) return true;
}
return false;
}
else
{
$test = false;
// thats why you realy have to care about what you put in filters and data :)
eval('$test = (' . $fv . ');');
if( $test ) return true;
}
return false;
};
/*
* Filtering
*/
$result = array();
foreach($rows as $row)
{
$r = array();
foreach($filters as $fk => $fv)
{
$r[] = $applyFilter($row, $fk, $fv);
}
$r = array_filter($r);
if( count($r) == count($filters) )
{
$result[] = $row;
}
}
return $result;
}
以防止出现极大的安全风险。
eval
现在返回一个函数,返回一个简单的测试依赖
您设置的操作(您甚至可以定义自定义测试)buildFilter
因此修改了:)这是新代码
ApplyFilter