Php 在集合上使用聚合函数实现类似SQL的group by的算法?
假设有这样一个数组:Php 在集合上使用聚合函数实现类似SQL的group by的算法?,php,javascript,python,algorithm,collections,Php,Javascript,Python,Algorithm,Collections,假设有这样一个数组: [ {'id' : 1, 'closed' : 1 }, {'id' : 2, 'closed' : 1 }, {'id' : 5, 'closed' : 1 }, {'id' : 7, 'closed' : 0 }, {'id' : 8, 'closed' : 0 }, {'id' : 9, 'closed' : 1 } ] [ {'id__min' : 1, 'id__max' : 5, 'closed' : 1}, {'id__min
[
{'id' : 1, 'closed' : 1 },
{'id' : 2, 'closed' : 1 },
{'id' : 5, 'closed' : 1 },
{'id' : 7, 'closed' : 0 },
{'id' : 8, 'closed' : 0 },
{'id' : 9, 'closed' : 1 }
]
[
{'id__min' : 1, 'id__max' : 5, 'closed' : 1},
{'id__min' : 7, 'id__max' : 8, 'closed' : 0},
{'id__min' : 9, 'id__max' : 9, 'closed' : 1}
]
我想总结一下这个数据集(不使用SQL!),并获取由行'closed'
变量定义的每个组的min
和max
id。产生如下输出:
[
{'id' : 1, 'closed' : 1 },
{'id' : 2, 'closed' : 1 },
{'id' : 5, 'closed' : 1 },
{'id' : 7, 'closed' : 0 },
{'id' : 8, 'closed' : 0 },
{'id' : 9, 'closed' : 1 }
]
[
{'id__min' : 1, 'id__max' : 5, 'closed' : 1},
{'id__min' : 7, 'id__max' : 8, 'closed' : 0},
{'id__min' : 9, 'id__max' : 9, 'closed' : 1}
]
这只是我想做的一个例子。我想实现一些类似于python的itertools.groupby
提供的东西,但要更全面一些。(希望定义我自己的聚合函数)
我正在寻找指针,伪代码,甚至任何PHP,Python或Javascript代码,如果可能的话
谢谢 的
键
参数允许您传递自己的聚合函数。Ruby代码:
def summarise array_of_hashes
#first sort the list by id
arr = array_of_hashes.sort {|a, b| a['id'] <=> b['id'] }
#create a hash with id_min and id_max set to the id of the first
#array element and closed to the closed of the first array element
hash = {}
hash['id_min'] = hash['id_max'] = arr[0]['id']
hash['closed'] = arr[0]['closed']
#prepare an output array
output = []
#iterate over the array elements
arr.each do |el|
if el['closed'] == hash['closed']
#update id_max while the id value is the same
hash['id_max'] = el['id']
else #once it is different
output.push hash #add the hash to the output array
hash = {} #create a new hash in place of the old one
#and initiate its keys to the appropriate values
hash['id_min'] = hash['id_max'] = el['id']
hash['closed'] = el['closed']
end
end
output.push hash #make sure the final hash is added to the output array
#return the output array
output
end
下面的代码将适用于您的示例:
my_condition = lambda do |a, b|
b['closed'] == a['closed']
end
my_group_func = lambda do |to_group|
{
'id_min' => to_group[0]['id'],
'id_max' => to_group[to_group.length-1]['id'],
'closed' => to_group[0]['closed']
}
end
summarise(my_array.sort {|a, b| a['id'] <=> b['id']}, my_condition, my_group_func)
my_condition=lambda do|a,b|
b['closed']==a['closed']
结束
my_group_func=lambda do|to_group|
{
'id_min'=>到组[0]['id'],
'id_max'=>to_group[to_group.length-1]['id'],
“已关闭”=>至_组[0][“已关闭”]
}
结束
总结(my|array.sort{a,b|a['id']b['id']},my|U条件,my|U组_func)
通用算法将适用于任何允许将函数作为参数传递给其他函数的语言。如果使用了正确的条件和聚合函数,它还可以处理任何数据类型的变量数组。一个PHP版本的Ruby代码,具有稍微通用的命名和id顺序处理:
$input = array(
array('id' => 3, 'closed' => 1),
array('id' => 2, 'closed' => 1),
array('id' => 5, 'closed' => 1),
array('id' => 7, 'closed' => 0),
array('id' => 8, 'closed' => 0),
array('id' => 9, 'closed' => 1)
);
$output = min_max_group($input, 'id', 'closed');
echo '<pre>'; print_r($output); echo '</pre>';
function min_max_group($array, $name, $group_by)
{
$output = array();
$tmp[$name.'__max'] = $tmp[$name.'__min'] = $array[0][$name];
$tmp[$group_by] = $array[0][$group_by];
foreach($array as $value)
{
if($value[$group_by] == $tmp[$group_by])
{
if($value[$name] < $tmp[$name.'__min']) { $tmp[$name.'__min'] = $value[$name]; }
if($value[$name] > $tmp[$name.'__max']) { $tmp[$name.'__max'] = $value[$name]; }
}
else
{
$output[] = $tmp;
$tmp[$name.'__max'] = $tmp[$name.'__min'] = $value[$name];
$tmp[$group_by] = $value[$group_by];
if($value[$name] < $tmp[$name.'__min']) { $tmp[$name.'__min'] = $value[$name]; }
if($value[$name] > $tmp[$name.'__max']) { $tmp[$name.'__max'] = $value[$name]; }
}
}
$output[] = $tmp;
return $output;
}
$input=array(
数组('id'=>3,'closed'=>1),
数组('id'=>2,'closed'=>1),
数组('id'=>5,'closed'=>1),
数组('id'=>7,'closed'=>0),
数组('id'=>8,'closed'=>0),
数组('id'=>9,'closed'=>1)
);
$output=min_max_组($input,'id','closed');
回声';打印(输出);回声';
函数min\u max\u group($array、$name、$group\u by)
{
$output=array();
$tmp[$name.''最大']=$tmp[$name.''最小']=$array[0][$name];
$tmp[$group_by]=$array[0][$group_by];
foreach($array作为$value)
{
如果($value[$group\u by]=$tmp[$group\u by])
{
如果($value[$name]<$tmp[$name.'''']){$tmp[$name.''''']=$value[$name];}
如果($value[$name]>$tmp[$name.''最大值']){$tmp[$name.''最大值']=$value[$name];}
}
其他的
{
$output[]=$tmp;
$tmp[$name.''最大']=$tmp[$name.''最小']=$value[$name];
$tmp[$group\U by]=$value[$group\U by];
如果($value[$name]<$tmp[$name.'''']){$tmp[$name.''''']=$value[$name];}
如果($value[$name]>$tmp[$name.''最大值']){$tmp[$name.''最大值']=$value[$name];}
}
}
$output[]=$tmp;
返回$output;
}
也许我误解了这个问题,但这不只是一个标准问题吗?我知道,我正在寻找一种通用的方法来用另一种语言(PHP)实现它。文档中给出了与较低级别代码中的函数等效的方法。尽管我需要的是推广这种方法,但这是可行的。这意味着能够传递我自己的聚合函数,或者以标准方式定义创建新分组的条件。我已经编辑了我的答案,给出了一个通用版本。我希望代码+注释足以允许移植到其他语言。是的,我知道如何使用特定数据来完成这项工作,我正在寻找方法对其进行泛化。该函数接受任何数组,并提取指定的一列,由指定的另一列分组,然后使用指定的名称返回常规数组。我想我遗漏了你想概括的其他内容?我只能假设您希望定义分组函数等?确切地说,我需要一种通用的方法来实现回调,我可以将回调传递给函数,以提取组值的min
或max
或我希望的任何值。另外,定义用于确定新组的比较函数的方法(可能指定多个字段等)。:-)用户定义的回调在PHP中很容易:。然后,您可以只传入函数名/参数等,让其他函数处理分组测试等。在我看来,一旦您定义了其中的几个函数,您最好直接调用其他函数,而不是将它们推到上面(这基本上只是一个数组循环)…您不妨说,“为什么不直接使用数据处理?”