Как выполнить итерации более чем двух массивов сразу?

Попробуйте следующее: -

SET @start_res = 20150301;
SET @finish_res= 20150501;
SET @finish_check= 20150801;
SET @start_check= 20150301;
SET @daily_hos= 3;

SELECT 

(SELECT COUNT(DAY_IN) AS arr FROM t_hospital WHERE 
DAY_IN between  @start_check and @finish_check and 
RES_DATE between @start_res and @finish_res and 
ID_daily_hos =@daily_hos) e,

(SELECT COUNT(PAT_STATUS) AS ONG1 FROM t_hospital WHERE 
PAT_STATUS  like '%ong%' and  
DAY_IN between @start_check and @finish_check and 
RES_DATE between @start_res and @finish_res  and 
ID_daily_hos =@daily_hos) a,

(SELECT COUNT(PAT_STATUS) AS RTED FROM t_hospital WHERE 
PAT_STATUS  like '%rtde%' and  
DAY_IN between  @start_check and @finish_check and 
RES_DATE between @start_res and @finish_res  and 
ID_daily_hos =@daily_hos)b,

(SELECT COUNT(PAT_STATUS) AS POLI FROM t_hospital WHERE 
PAT_STATUS  like '%pol%' and 
DAY_IN between @start_check and @finish_check and 
RES_DATE between @start_res and @finish_res  and 
ID_daily_hos =@daily_hos) c,

(SELECT COUNT(PAT_STATUS) AS para FROM t_hospital WHERE 
PAT_STATUS  like '%para%' and  
DAY_IN between @start_check and @finish_check and 
RES_DATE between @start_res and @finish_res  and 
ID_daily_hos =@daily_hos) d

В вашем вопросе упоминается о соединении двух таблиц, но, похоже, имеется только t_hospital. Возможно, вы захотите обновить свой вопрос информацией о другой таблице.

14
задан JSBձոգչ 30 January 2009 в 18:50
поделиться

6 ответов

если существует то же количество имен столбцов, поскольку существуют элементы в каждой строке, разве Вы не могли использовать для цикла?

var currentValues = currentRow.Split(separatorChar);

for(var i=0;i<columnList.Length;i++){
   // use i to index both (or all) arrays and build your map
}
17
ответ дан 1 December 2019 в 06:16
поделиться

На функциональном языке Вы обычно находили бы функцию "zip", которая, надо надеяться, будет частью C#4.0. Bart Де-Смет обеспечивает забавную реализацию zip на основе существующих функций LINQ:

public static IEnumerable<TResult> Zip<TFirst, TSecond, TResult>(
  this IEnumerable<TFirst> first, 
  IEnumerable<TSecond> second, 
  Func<TFirst, TSecond, TResult> func)
{
  return first.Select((x, i) => new { X = x, I = i })
    .Join(second.Select((x, i) => new { X = x, I = i }), 
    o => o.I, 
    i => i.I, 
    (o, i) => func(o.X, i.X));
}

Затем можно сделать:

  int[] s1 = new [] { 1, 2, 3 };
  int[] s2 = new[] { 4, 5, 6 };
  var result = s1.Zip(s2, (i1, i2) => new {Value1 = i1, Value2 = i2});
4
ответ дан 1 December 2019 в 06:16
поделиться

У Вас есть неочевидная псевдоошибка в Вашем первоначальном коде - IEnumerator<T>, расширяется IDisposable, таким образом, необходимо расположить его. Это может быть очень важно с блоками итератора! Не проблема для массивов, но был бы с другим IEnumerable<T> реализации.

я сделал бы это как это:

public static IEnumerable<TResult> PairUp<TFirst,TSecond,TResult>
    (this IEnumerable<TFirst> source, IEnumerable<TSecond> secondSequence,
     Func<TFirst,TSecond,TResult> projection)
{
    using (IEnumerator<TSecond> secondIter = secondSequence.GetEnumerator())
    {
        foreach (TFirst first in source)
        {
            if (!secondIter.MoveNext())
            {
                throw new ArgumentException
                    ("First sequence longer than second");
            }
            yield return projection(first, secondIter.Current);
        }
        if (secondIter.MoveNext())
        {
            throw new ArgumentException
                ("Second sequence longer than first");
        }
    }        
}

Затем можно снова использовать это каждый раз, когда у Вас есть потребность:

foreach (var pair in columnList.PairUp(currentRow.Split(separatorChar),
             (column, value) => new { column, value })
{
    // Do something
}

, Кроме того, Вы могли создать универсальный Парный тип и избавиться от параметра проекции в методе PairUp.

РЕДАКТИРОВАНИЕ:

С Парным типом, код вызова был бы похож на это:

foreach (var pair in columnList.PairUp(currentRow.Split(separatorChar))
{
    // column = pair.First, value = pair.Second
}

, Который наводит справки столь простой, как можно добраться. Да, необходимо поместить служебный метод где-нибудь как повторно используемый код. Едва проблема, по моему мнению. Теперь для нескольких массивов...

, Если массивы имеют различные типы, у нас есть проблема. Вы не можете выразить произвольного числа параметров типа в общем методе / описание типа - Вы могли записать версии PairUp для стольких параметров типа, сколько Вы хотели, точно так же, как существует Action и Func делегаты максимум к 4 параметрам делегата - но Вы не можете сделать это произвольным.

, Если значения будут все иметь тот же тип, однако - и если Вы рады придерживаться массивов - это легко. (Немассивы хорошо также, но Вы не можете сделать длины, проверяющей заранее.) Вы могли сделать это:

public static IEnumerable<T[]> Zip<T>(params T[][] sources)
{
    // (Insert error checking code here for null or empty sources parameter)

    int length = sources[0].Length;
    if (!sources.All(array => array.Length == length))
    {
        throw new ArgumentException("Arrays must all be of the same length");
    }

    for (int i=0; i < length; i++)
    {
        // Could do this bit with LINQ if you wanted
        T[] result = new T[sources.Length];
        for (int j=0; j < result.Length; j++)
        {
             result[j] = sources[j][i];
        }
        yield return result;
    }
}

Затем код вызова был бы:

foreach (var array in Zip(columns, row, whatevers))
{
    // column = array[0]
    // value = array[1]
    // whatever = array[2]
}

Это включает определенное количество копирования, конечно - Вы создаете массив каждый раз. Вы могли изменить это путем представления другого типа как это:

public struct Snapshot<T>
{
    readonly T[][] sources;
    readonly int index;

    public Snapshot(T[][] sources, int index)
    {
        this.sources = sources;
        this.index = index;
    }

    public T this[int element]
    {
        return sources[element][index];
    }
}

Это, вероятно, рассматривалось бы как излишество большинством, хотя ;)

я мог продолжать придумывать все виды идей, быть честным..., но основы:

  • С определенной допускающей повторное использование работой, можно сделать код вызова более хорошим
  • Для произвольных комбинаций типов, необходимо будет сделать каждое количество параметров (2, 3, 4...) отдельно из-за пути работы дженериков
  • , Если Вы рады использовать тот же тип для каждой части, можно сделать лучше
22
ответ дан 1 December 2019 в 06:16
поделиться

Используйте IEnumerator для обоих, был бы хороши

var currentValues = currentRow.Split(separatorChar);
using (IEnumerator<string> valueEnum = currentValues.GetEnumerator(), columnEnum = columnList.GetEnumerator()) {
    while (valueEnum.MoveNext() && columnEnum.MoveNext())
        valueMap.Add(columnEnum.Current, valueEnum.Current);
}

Или создал бы дополнительные методы

public static IEnumerable<TResult> Zip<T1, T2, TResult>(this IEnumerable<T1> source, IEnumerable<T2> other, Func<T1, T2, TResult> selector) {
    using (IEnumerator<T1> sourceEnum = source.GetEnumerator()) {
        using (IEnumerator<T2> otherEnum = other.GetEnumerator()) {
            while (sourceEnum.MoveNext() && columnEnum.MoveNext())
                yield return selector(sourceEnum.Current, otherEnum.Current);
        }
    }
}

Использование

var currentValues = currentRow.Split(separatorChar);
foreach (var valueColumnPair in currentValues.Zip(columnList, (a, b) => new { Value = a, Column = b }) {
    valueMap.Add(valueColumnPair.Column, valueColumnPair.Value);
}
3
ответ дан 1 December 2019 в 06:16
поделиться

При реальном использовании массивов лучший способ состоит в том, чтобы, вероятно, только использовать стандартное for цикл с индексами. Не как хорошая, предоставленный, но насколько я знаю.NET не предлагает лучший способ сделать это.

Вы могли также инкапсулировать свой код в метод, названный zip †“, это - общая функция списка высшего порядка. Однако C#, испытывающий недостаток в подходящем Типе "кортеж", это является довольно неработоспособным. Вы закончили бы тем, что возвратились IEnumerable<KeyValuePair<T1, T2>>, который не очень хорош.

Между прочим, Вы действительно используете IEnumerable вместо IEnumerable<T> или почему Вы бросаете эти Current значение?

3
ответ дан 1 December 2019 в 06:16
поделиться

Вместо того, чтобы создать два отдельных массива Вы могли сделать двухмерную антенную решетку или словарь (который будет лучше). Но действительно, если это работает, я не попытался бы изменить его.

2
ответ дан 1 December 2019 в 06:16
поделиться
Другие вопросы по тегам:

Похожие вопросы: