Использование рекурсивного соответствия в PHP-регулярном выражении значительно быстрее процедурного соответствия скобок. особенно с более длинными строками.
http://php.net/manual/en/regexp.reference.recursive.php
, например
$patt = '!\( (?: (?: (?>[^()]+) | (?R) )* ) \)!x';
preg_match_all( $patt, $str, $m );
vs.
matchBrackets( $str );
function matchBrackets ( $str, $offset = 0 ) {
$matches = array();
list( $opener, $closer ) = array( '(', ')' );
// Return early if there's no match
if ( false === ( $first_offset = strpos( $str, $opener, $offset ) ) ) {
return $matches;
}
// Step through the string one character at a time storing offsets
$paren_score = -1;
$inside_paren = false;
$match_start = 0;
$offsets = array();
for ( $index = $first_offset; $index < strlen( $str ); $index++ ) {
$char = $str[ $index ];
if ( $opener === $char ) {
if ( ! $inside_paren ) {
$paren_score = 1;
$match_start = $index;
}
else {
$paren_score++;
}
$inside_paren = true;
}
elseif ( $closer === $char ) {
$paren_score--;
}
if ( 0 === $paren_score ) {
$inside_paren = false;
$paren_score = -1;
$offsets[] = array( $match_start, $index + 1 );
}
}
while ( $offset = array_shift( $offsets ) ) {
list( $start, $finish ) = $offset;
$match = substr( $str, $start, $finish - $start );
$matches[] = $match;
}
return $matches;
}
Использовать анонимный тип.
Например
group x by new { x.Column1, x.Column2 }
Хотя этот вопрос задает вопрос о свойствах класса по классу, если вы хотите группировать по нескольким столбцам в отношении объекта ADO (например, DataTable), вам нужно назначить свои «новые» элементы для переменных:
EnumerableRowCollection<DataRow> ClientProfiles = CurrentProfiles.AsEnumerable()
.Where(x => CheckProfileTypes.Contains(x.Field<object>(ProfileTypeField).ToString()));
// do other stuff, then check for dups...
var Dups = ClientProfiles.AsParallel()
.GroupBy(x => new { InterfaceID = x.Field<object>(InterfaceField).ToString(), ProfileType = x.Field<object>(ProfileTypeField).ToString() })
.Where(z => z.Count() > 1)
.Select(z => z);
Вы также можете использовать Tuple & lt;> для строго типизированной группировки.
from grouping in list.GroupBy(x => new Tuple<string,string,string>(x.Person.LastName,x.Person.FirstName,x.Person.MiddleName))
select new SummaryItem
{
LastName = grouping.Key.Item1,
FirstName = grouping.Key.Item2,
MiddleName = grouping.Key.Item3,
DayCount = grouping.Count(),
AmountBilled = grouping.Sum(x => x.Rate),
}
.GroupBy(x => x.Column1 + " " + x.Column2)
Linq.Enumerable.Aggregate()
это даже позволяет группировать динамическое число свойств: propertyValues.Aggregate((current, next) => current + " " + next)
.
– Kai Hartmann
1 August 2017 в 07:51
.GroupBy(x => (x.MaterialID, x.ProductID))
Для группы по нескольким столбцам, попробуйте это вместо ...
GroupBy(x=> new { x.Column1, x.Column2 }, (key, group) => new
{
Key1 = key.Column1,
Key2 = key.Column2,
Result = group.ToList()
});
Точно так же вы можете добавить Column3, Column4 и т. д.
Result
содержит все наборы данных, связанные со всеми столбцами. Большое спасибо!
– j00hi
15 September 2016 в 10:26
С C # 7 вы также можете использовать кортежи значений:
group x by (x.Column1, x.Column2)
или
.GroupBy(x => (x.Column1, x.Column2))
Следует отметить, что вам нужно отправить объект для лямбда-выражений и не использовать экземпляр для класса.
Пример:
public class Key
{
public string Prop1 { get; set; }
public string Prop2 { get; set; }
}
Это будет скомпилировать, но будет генерировать один ключ за каждый цикл.
var groupedCycles = cycles.GroupBy(x => new Key
{
Prop1 = x.Column1,
Prop2 = x.Column2
})
Если вы не укажете свойства ключа, а затем отработаете их, вы можете сделать это так. Это будет GroupBy
правильно и даст вам ключевые свойства.
var groupedCycles = cycles.GroupBy(x => new
{
Prop1 = x.Column1,
Prop2= x.Column2
})
foreach (var groupedCycle in groupedCycles)
{
var key = new Key();
key.Prop1 = groupedCycle.Key.Prop1;
key.Prop2 = groupedCycle.Key.Prop2;
}
Образец процедуры
.GroupBy(x => new { x.Column1, x.Column2 })
var Results= query.GroupBy(f => new { /* add members here */ });
Ok получил это как:
var query = (from t in Transactions
group t by new {t.MaterialID, t.ProductID}
into grp
select new
{
grp.Key.MaterialID,
grp.Key.ProductID,
Quantity = grp.Sum(t => t.Quantity)
}).ToList();