我正在编写一个方法,该方法需要一个$topicNames
数组和一个$app
数组,并将每个$app
与$topicNames
串联起来,如下所示:
public function getNotificationTopicByAppNames(array $topicNames, array $apps)
{
$topics = [];
foreach ($topicNames as $topicName) {
foreach ($apps as $app) {
$topic = $app . '_' . $topicName;
$topics[] = $topic;
}
}
return $topics;
}
}
输入和结果如下...
$topicNames = [
'one_noti',
'two_noti',
'three_noti'
];
$apps = [
'one_app',
'two_app'
];
// The return result of the method will be like the following
[
'one_app_one_noti',
'two_app_one_noti',
'one_app_two_noti',
'two_app_two_noti',
'one_app_three_noti',
'two_app_three_noti'
]
我的问题是代替嵌套循环,还有其他方法吗?为什么要避免嵌套循环?因为目前,我有$topic
。稍后,我可能要添加languages
,locations
等...
我知道我可以使用map, reduce, array_walks, each
那些基本上是一个接一个地进行的操作。可以替代我可以使用的另一种替代方法吗?我可以更改其他数据类型而不是数组。
答案 0 :(得分:2)
如果您不关心订单,可以使用此
function getNotificationTopicByAppNames(array $topicNames, array $apps)
{
$topics = [];
foreach($apps as $app){
$topics = array_merge($topics, preg_filter('/^/', $app.'_', $topicNames));
}
return $topics;
}
print_r(getNotificationTopicByAppNames($topicNames,$apps));
输出
Array
(
[0] => one_app_one_noti
[1] => one_app_two_noti
[2] => one_app_three_noti
[3] => two_app_one_noti
[4] => two_app_two_noti
[5] => two_app_three_noti
)
您还可以切换循环,并使用$
代替后缀而不是前缀。事实证明这与您的顺序相同。我想到将前缀作为删除循环的一种方式。然后我想为什么不翻转它。
function getNotificationTopicByAppNames(array $topicNames, array $apps)
{
$topics = [];
foreach($topicNames as $topic){
$topics = array_merge($topics, preg_filter('/$/', '_'.$topic, $apps));
}
return $topics;
}
print_r(getNotificationTopicByAppNames($topicNames,$apps));
输出
Array
(
[0] => one_app_one_noti
[1] => two_app_one_noti
[2] => one_app_two_noti
[3] => two_app_two_noti
[4] => one_app_three_noti
[5] => two_app_three_noti
)
这里的诀窍是使用preg_filter
。
http://php.net/manual/en/function.preg-filter.php
preg_filter —执行正则表达式搜索并替换
因此,我们以^
开头或$
结尾进行搜索,该搜索不会捕获要替换的任何内容,然后我们只添加想要的内容。当我想给整个数组添加前缀等时,我就使用过此方法。
我无法在类中对其进行测试,因此我将其设置为常规函数,因此请根据需要进行调整。
干杯!
答案 1 :(得分:1)
您可以使用:
<?php
public function mergeStacks(...$stacks)
{
$allStacks = call_user_func_array('array_merge', $stacks);
return $this->concatString($allStacks);
}
private function concatString(&$stack, $index = 0, &$result = [])
{
if(count($stack) == 0){
return '';
}
if($index == count($stack)){
return $result;
}
array_walk($stack, function($value, $key) use($index, &$result, $stack){
if($key > $index){
array_push($result, $stack[$index] . '_' . $value);
}
});
$index = $index + 1;
return $this->concatString($stack, $index, $result);
}
然后,当您想要获取数组时,无论您是否有语言或主题等,都可以:
$this->mergeStacks($languages, $topics, $locations, .....);
其中$ languages,$ topics,$ locations是简单数组。
答案 2 :(得分:0)
请尝试以下操作,而不是仅接受主题名称参数:
function getNotificationTopicByAppNames(array $apps, array ...$names)
{
$topics = [];
foreach ($names as $nameArray) {
foreach ($nameArray as $topicName) {
foreach ($apps as $app) {
$topic = $app . '_' . $topicName;
$topics[] = $topic;
}
}
}
return $topics;
}
$topicNames = [
'one_noti',
'two_noti',
'three_noti'
];
$languagesNames = [
'test_en',
'test_other',
'test_other2'
];
$apps = [
'one_app',
'two_app'
];
print_r(getNotificationTopicByAppNames($apps,$topicNames,$languagesNames));
您可以将任意数量的数组传递给数组。