我正在构建一个职业页面,从托管的json文件中读取可用的职位。我很难让数据正确地过滤,而不仅仅是在值上。
此示例在与$data数组中设置的键/值进行比较时,只尝试输出来自$filter数组的匹配值:
<?php
/* ----------------------
Dump the output
---------------------- */
function dump($data) {
if(is_array($data)) { //If the given variable is an array, print using the print_r function.
print "<pre>\n";
print_r($data);
print "</pre>";
} elseif (is_object($data)) {
print "<pre>\n";
var_dump($data);
print "</pre>";
} else {
print "=========> ";
var_dump($data);
print " <=========";
}
}
/* ----------------------
Sanitize a string to url friendly
---------------------- */
function cleanString($str) {
$removetags = array("'", '"', ',', '.', '?', '& ', '& ', '/', '#', '@','(',')');
$removespace[] = ' ';
$notags = str_replace($removetags,"",$str);
$nospaces = strtolower(str_replace($removespace,"-",$notags));
return preg_replace('~-{2,}~', '-', $nospaces);
}
function sanitizeString($val) {
if(is_array($val)) {
$array = array() ;
foreach ($val as $key => $value) {
$array[$key] = cleanString($value);
}
return $array;
} else {
$result = cleanString($val);
}
return $result;
}
/* ----------------------
Filter the array data, should match all values;=
---------------------- */
function filterData($array, $filter) {
$result = array();
foreach ($filter as $gk => $gv) {
foreach ($array as $key => $value) {
if (array_key_exists($gk, $value) && !empty($value[$gk])) {
if(is_array($value[$gk])) {
$child = array_search($gv, sanitizeString($value[$gk]));
if(!empty($value[$gk][$child])) {
$theValue = sanitizeString($value[$gk][$child]);
if ($theValue === $gv ) {
array_push($result,$value);
}
}
} else {
$theValue = sanitizeString($value[$gk]);
if ($theValue === $gv ) {
array_push($result,$value);
}
}
}
}
}
return (!empty($result)) ? $result : $array;
};
// sample data
$data = '{"jobs":[{"department":"sales","location":{"country":"United States","country_code":"US","region":"New York","region_code":"NY","city":"New York","zip_code":null,"telecommuting":false}},{"department":null,"location":{"country":"United Kingdom","country_code":"GB","region":"England","region_code":"England","city":"Leeds","zip_code":null,"telecommuting":false}},{"department":"Project Management","location":{"country":"United Kingdom","country_code":"GB","region":"England","region_code":"England","city":"Manchester","zip_code":null,"telecommuting":false}},{"department":"Project Management","location":{"country":"United Kingdom","country_code":"GB","region":"England","region_code":"England","city":"London","zip_code":null,"telecommuting":false}},{"department":"Customer Success","location":{"country":"United Kingdom","country_code":"GB","region":"England","region_code":"England","city":"London","zip_code":null,"telecommuting":false}},{"department":null,"location":{"country":"United Kingdom","country_code":"GB","region":"England","region_code":"England","city":"London","zip_code":null,"telecommuting":false}}]}';
$decode = json_decode($data, true);
// sample filter - values should be lowercase, and sanitised;
$filter = array (
'department' => 'project-management',
'location' => 'london'
);
$filterdata = filterData($decode['jobs'], $filter);
$i = 1;
foreach ($filterdata as $res) {
echo $i . '<br />';
echo $res['department'] . '<br />';
echo $res['location']['city'] . '<hr />';
$i++;
}
?>我发现,filterData函数将返回与$filter数组中的任意设置键/值匹配的结果。因此,如果部门和地点都匹配,我就可以得到重复的条目。
如何调整这一点,以便只得到所有$filter键/值匹配的数组输出?
谢谢--我已经花了一天时间在这件事上了,我不再做进一步的事情了,所以任何正确的方向上的帮助都将是非常感谢的。
发布于 2018-05-09 06:36:46
注:我可能不太理解你的问题,但,由于还没有答案,我决定尝试。如果我的猜测是错误的,让我知道,我会相应地修改我的答案。
现在,我将忽略您的cleanString & sanitizeString函数。我相信,在解决了工作过滤部分后,您可以轻松地执行这些任务。
要筛选任何数据数组,过滤器()是您最好的朋友。
array_filter()遍历数组中的每个值,将它们传递给回调函数。如果回调函数返回true,则从数组返回当前值到结果数组。保留数组键。
在array_filter()回调中,循环检查筛选规则,并检查$job是否匹配它的属性。
如果所有规则匹配,我们将返回true,否则为false (这将筛选出数组中的作业)。
$data = '{"jobs":[{"department":"sales","location":{"country":"United States","country_code":"US","region":"New York","region_code":"NY","city":"New York","zip_code":null,"telecommuting":false}},{"department":null,"location":{"country":"United Kingdom","country_code":"GB","region":"England","region_code":"England","city":"Leeds","zip_code":null,"telecommuting":false}},{"department":"Project Management","location":{"country":"United Kingdom","country_code":"GB","region":"England","region_code":"England","city":"Manchester","zip_code":null,"telecommuting":false}},{"department":"Project Management","location":{"country":"United Kingdom","country_code":"GB","region":"England","region_code":"England","city":"London","zip_code":null,"telecommuting":false}},{"department":"Customer Success","location":{"country":"United Kingdom","country_code":"GB","region":"England","region_code":"England","city":"London","zip_code":null,"telecommuting":false}},{"department":null,"location":{"country":"United Kingdom","country_code":"GB","region":"England","region_code":"England","city":"London","zip_code":null,"telecommuting":false}}]}';
$decode = json_decode($data, true);
$filters = array(
'department' => 'Project Management',
'location' => 'London'
);
/**
* We will use array_filter()
* to filter out jobs that doesn't meet our rules
*/
$filterData = array_filter($decode['jobs'], function($job) use($filters) {
$matched = [];
foreach ($filters as $col => $val) {
if (isset($job[$col]) === false) {
$matched[0] = '';
continue;
}
/**
* I am assigning filter condition to $matched key
* PHP as a dynamic language, will convert boolean to integer
*
* If you don't like this approach, you can try assigning to value
*/
if (is_array($job[$col])) {
$matched[in_array($val, $job[$col])] = '';
} else {
$matched[($job[$col] === $val)] = '';
}
}
/**
* If any of our rules returned false
* We will return false too
* and array_filter will filter out this job
*/
return isset($matched[0]) === false;
});
print_r($filterData);https://stackoverflow.com/questions/50238049
复制相似问题