private function processCompare(array $tables, Config $config)
{
if (!isset($config['compare'])) {
return $tables;
}
$conditions = array_diff($config['cols'], $this->statKeys, [$config['compare']]);
$compare = $config['compare'];
$compareFields = $config['compare_fields'];
return F\map($tables, function ($table) use($conditions, $compare, $compareFields) {
$groups = F\group($table, function ($row) use($conditions, $compare, $compareFields) {
$values = array_intersect_key($row->getArrayCopy(), array_flip($conditions));
return F\reduce_left($values, function ($value, $i, $c, $reduction) {
return $reduction . $value;
});
});
$table = [];
$colNames = null;
foreach ($groups as $group) {
$firstRow = null;
foreach ($group as $row) {
if (null === $firstRow) {
$firstRow = $row->newInstance(array_diff_key($row->getArrayCopy(), array_flip($this->statKeys)));
if (isset($firstRow[$compare])) {
unset($firstRow[$compare]);
}
foreach ($compareFields as $compareField) {
if (isset($firstRow[$compareField])) {
unset($firstRow[$compareField]);
}
}
}
if (null === $colNames) {
$colNames = array_combine($firstRow->getNames(), $firstRow->getNames());
}
$compared = $row[$compare];
foreach ($compareFields as $compareField) {
$name = $compare . ':' . $compared . ':' . $compareField;
$name = $this->resolveCompareColumnName($firstRow, $name);
$firstRow[$name] = $row[$compareField];
$colNames[$name] = $name;
// we invent a new col name here, use the compare field's class.
$this->classMap[$name] = $this->classMap[$compareField];
}
}
$table[] = $firstRow;
}
$table = F\map($table, function ($row) use($colNames) {
$newRow = $row->newInstance([]);
foreach ($colNames as $colName) {
$newRow[$colName] = isset($row[$colName]) ? $row[$colName] : null;
}
return $newRow;
});
return $table;
});
return $tables;
}