array(
[0]=>
[index1]=>something
[index2]=>something else
[index3]=>something more
[1]=>
[index1]=>something
[index2]=>something else
[index3]=>something more
[2]=>
[index1]=>something
[index2]=>something else
[index3]=>something more
)
编辑: 所以我想检索以下内容:
array(
[0]=>
[index1]=>something
[index2]=>something else
[1]=>
[index1]=>something
[index2]=>something else
[2]=>
[index1]=>something
[index2]=>something else
)
如何使用cakephp中的Set :: extract函数获取数组的多个索引?
这将检索一个值:
Set::extract($array, '{n}.index1');
但我希望获得多个值...比如,index1和index2。
我尝试了以下的陈述,但没有用。
Set::extract($array, '[{n}.index1, {n}.index2']);
修改
$__pages = Hash::merge(
Hash::extract($pages, 'pages.{n}.id'),
Hash::extract($pages, 'pages.{n}.title')
);
pr($__pages);
输出:
Array
(
[0] => 2
[1] => 4
[2] => 104
[3] => Sample Page
[4] => about us
[5] => Services
)
这对我没有帮助,因为我仍然需要这样的关联:
Array(
[2] => Sample Page
[4] => About us
[104] => Services
)
我甚至会满意:
Array(
Array(id => 2, title => Sample Page)
Array(id => 4, title => About Us)
Array(id => 104, title => Services)
)
ANSWER
thecodeparadox的答案适用于我提供的测试代码。这是现实生活中的代码,以防有人在这里绊倒。
它在书中指出,“除{n}和{s}之外的括号中的任何字符串文字都被解释为正则表达式。”
这条线似乎是隐藏的,而不是非常明显。所以知道这一点,我只是使用正则表达式规则来检索我需要的数据。我有一个数组从api中提取wordpress帖子,我需要将结果缩小到id, title
。
array(
posts=>
0=>
id => 3
slug => sample-page
type => page
title => Sample Page
//...and so on
1=>
id => 7
slug => sample-page-2
type => page
title => Sample Page 2
//...and so on
为了只检索id和标题,我添加了以下行。
pr(Set::classicExtract($pages, 'pages.{n}.{(id|title)}'));
这给了我:
array(
posts=>
0=>
id => 3
title => Sample Page
1=>
id => 7
title => Sample Page 2
文件:Book
答案 0 :(得分:6)
$arr = array(
array(
'index1'=>'something',
'index2'=>'something else',
'index3'=>'something more',
),
array(
'index1'=>'something',
'index2'=>'something else',
'index3'=>'something more',
),
array(
'index1'=>'something',
'index2'=>'something else',
'index3'=>'something more',
)
);
$output = Set::classicExtract($arr, '{n}.{index[1-2]}');
print_r($output);
// output
Array
(
[0] => Array
(
[index1] => something
[index2] => something else
)
[1] => Array
(
[index1] => something
[index2] => something else
)
[2] => Array
(
[index1] => something
[index2] => something else
)
)
答案 1 :(得分:1)
您是否尝试过Set :: extract($ array,'{n}。{s}'); ?
编辑:如果您的数组维度与答案中的数组完全相同,则可以尝试使用array_keys(Set :: extract($ array,'{n}。{s}'));
答案 2 :(得分:1)
一种方式(如果你只想保留一些结果):
Hash::merge(
Hash::extract($array, '{n}.index1'),
Hash::extract($array, '{n}.index2')
);
另一种方式(如果你只想删除一些):
Hash::remove($array, '{n}.index3');
答案 3 :(得分:1)
我不确定你为什么要坚持使用Set
课程?如果它不适合您的需要,为什么你绝对使用它而不是创建自己的功能?
您在其中一条评论中表示要避免foreach
循环。但是Set
类方法充满了foreach
个循环。我可能会错过这一点......
Personnaly我会简单地用这样的函数来做:
function filter_fields($array_to_filter, $fields_to_keep)
{
foreach($array_to_filter as $i => $sub_array)
{
foreach($sub_array as $field => $value)
{
if(!in_array($field, $fields_to_keep))
{
unset($array_to_filter[$i][$field]);
}
}
}
return $array_to_filter;
}
以下是它将返回的示例:
print_r($array_to_filter);
/*
Array
(
[0] => Array
(
[index1] => abc
[index2] => def
[index3] => ghi
)
[1] => Array
(
[index1] => jkl
[index2] => mno
[index3] => poq
)
)
*/
$filtered_array = filter_fields($array_to_filter, array('index1', 'index3'));
print_r($filtered_array);
/*
Array
(
[0] => Array
(
[index1] => abc
[index3] => ghi
)
[1] => Array
(
[index1] => jkl
[index3] => poq
)
)
*/
答案 4 :(得分:1)
设置真棒!你不能直接使用Set :: extract来做这个,但你可以使用Set :: combine来构建两个数组索引的关联数组:
Set::combine($myArray, '{n}.index1', '{n}.index2')
一个工作示例如下所示:
$myArray = array(
array('index1'=>'something 1', 'index2'=>'something else 1', 'index3'=>'something more 1'),
array('index1'=>'something 2', 'index2'=>'something else 2', 'index3'=>'something more 2'),
array('index1'=>'something 3', 'index2'=>'something else 3', 'index3'=>'something more 3'),
);
debug(Set::combine($myArray, '{n}.index1', '{n}.index2'));
这将采用您提到的数组:
array(
[0]=>
[index1]=>something 1
[index2]=>something else 1
[index3]=>something more 1
[1]=>
[index1]=>something 2
[index2]=>something else 2
[index3]=>something more 2
[2]=>
[index1]=>something 3
[index2]=>something else 3
[index3]=>something more 3
)
并将其转换为:
Array (
[something1] => something else 1
[something2] => something else 2
[something3] => something else 3
)
答案 5 :(得分:1)
[+10]在这篇文章中向我揭示了classicExtract方法的大拇指。
示例数组:
$params = array(
'key-1'=>array('subkey'=>array('x'), 'junk'),
'key-2'=>array('subkey'=>array('y'), 'otherkey'=>'more junk')
);
我遇到的问题:
基本密钥转换为int。
eg. array(0=>array('x'), 1=>array('y'))
解决方案:
$array = Hash::filter(Set::classicExtract($params, '{[a-zA-Z0-9-_.]}.subkey'));
返回:
eg. array('key-1'=>array('x'), 'key-2'=>array('y'))
根据需要在密钥中修改正则表达式。
刚刚写了这个函数
它将使用{a)代替{s}
来解析数组{a}表示基础的关联键。
这样调用:static :: extract($ array,'{a} .subkey');
public static function extract($array, $path, $filter=true){
$path = str_replace("{a}", "{[a-zA-Z0-9-_.]}", $path);
if(is_array($array)){
$return = Set::classicExtract($array, $path);
if($filter){
if(is_array($return)){
$return = Hash::filter($return);
}
}
return $return;
}
}
[[蛋糕3的更新]]
如果您使用此功能,我看到cakephp刚删除了set类。您可以通过将classicExtract方法添加到类
来再次使用它use Cake\Utility\Hash;
public static function classicExtract($data, $path = null)
{
if (empty($path)) {
return $data;
}
if (is_object($data)) {
if (!($data instanceof \ArrayAccess || $data instanceof \Traversable)) {
$data = get_object_vars($data);
}
}
if (empty($data)) {
return null;
}
if (is_string($path) && strpos($path, '{') !== false) {
$path = \Cake\Utility\String::tokenize($path, '.', '{', '}');
} elseif (is_string($path)) {
$path = explode('.', $path);
}
$tmp = array();
if (empty($path)) {
return null;
}
foreach($path as $i => $key) {
if (is_numeric($key) && intval($key) > 0 || $key === '0') {
if (isset($data[$key])) {
$data = $data[$key];
} else {
return null;
}
} elseif ($key === '{n}') {
foreach($data as $j => $val) {
if (is_int($j)) {
$tmpPath = array_slice($path, $i + 1);
if (empty($tmpPath)) {
$tmp[] = $val;
} else {
$tmp[] = static::classicExtract($val, $tmpPath);
}
}
}
return $tmp;
} elseif ($key === '{s}') {
foreach($data as $j => $val) {
if (is_string($j)) {
$tmpPath = array_slice($path, $i + 1);
if (empty($tmpPath)) {
$tmp[] = $val;
} else {
$tmp[] = static::classicExtract($val, $tmpPath);
}
}
}
return $tmp;
} elseif (strpos($key, '{') !== false && strpos($key, '}') !== false) {
$pattern = substr($key, 1, -1);
foreach($data as $j => $val) {
if (preg_match('/^'.$pattern.'/s', $j) !== 0) {
$tmpPath = array_slice($path, $i + 1);
if (empty($tmpPath)) {
$tmp[$j] = $val;
} else {
$tmp[$j] = static::classicExtract($val, $tmpPath);
}
}
}
return $tmp;
} else {
if (isset($data[$key])) {
$data = $data[$key];
} else {
return null;
}
}
}
return $data;
}
//CAKEPHP METHODS
public static function extract($array, $path, $filter = true)
{
$return = [];
if (is_array($array)) {
if (stristr($path, '{a}')) {
$return = static::classicExtract($array, str_replace("{a}", "{[a-zA-Z0-9-_. ]}", $path));
} else {
$return = Hash::extract($array, $path);
}
}
if ($filter && is_array($return)) {
$return = Hash::filter($return);
}
return $return;
}