Здравствуйте, anton_t, Вы писали:
_>Открыл я для себя list comprehensions до linq-а, когда с питоном работал.
А я — когда с Хаскелем.
_>А linq сделан таким каким сделан для того, что бы можно было прикрутить у нему как списки и бд, так и другие источники данных, в том числе и те, о которых мс не знает.
Сделан он таким для того, чтобы можно было прикрутить у нему как списки и бд, так и другие источники данных — в этом ты совершенно прав. Но появился он в языке не из-за этого. Была некоторая важная, конкретная проблема. Или несколько. Linq появился, чтобы их решить, не просто так. И он был создан для того, чтобы их решить. Что это за проблема(ы)?
Здравствуйте, IT, Вы писали:
ГВ>>RSDN-ейшая из RSDN-ейших инквизиций требует от заблудшего признать существование минималистически глобального универсального всемогутера! Просто кристально чистый образец деления на нуль и умножения на пустое множество. Достоин внесения во всяческие анналы.
IT>Ты сильно не зарывайся. Обсуждение инквизиции запрещено правилами форума, за это можно на сутки-двое и на костерок загреметь.
Точно. Запрещено секретным пунктом правил. И в его подпункте написано, что IT лишен чувства юмора.
Здравствуйте, IT, Вы писали:
ГВ>>Вторая задача, кстати, тоже не совсем правильно решена — из-за Union могут быть проглочены соседние элементы, например на вот таком массиве { 1, 2, 3, 3, 4, 4, 5, 1, 1, 2 } ответ получается {1, 3, 4}, а должен быть как минимум {1, 3, 3, 4}.
IT>Я задачу понял именно так. Для твоего уточнения достаточно заменить Union на Cancat. И что значит выделенное, первая задача решена не правильно?
Нет, первая задача правильно решена. Выделенное значит, что ты ошибся в решении второй задачи на пару с Lloyd. Кстати говоря, замена Union на Concat приводит к другой ошибке: на данных { 1, 2, 3, 3, 4, 4, 5, 1, 1, 2 } результат получается {1, 1, 1, 3, 3, 4, 4}.
Я знаю только две бесконечные вещи — Вселенную и человеческую глупость, и я не совсем уверен насчёт Вселенной. (c) А. Эйнштейн
P.S.: Винодельческие провинции — это есть рулез!
Здравствуйте, VladD2, Вы писали:
VD>Ну, давай, моговед, поведай нам, что же Гапертон имел в виду под словами "простой" и "удобный" если слово "простой" он сам же охарактеризовал как имеющее 4 значения (пруфлинк
// ITvar arr = new[] { 1, 2, 3, 7, 8, 9, 10 };
var list = new List<int>();
Func<int,bool> func = i => { list.Add(i); return true; };
var q1 =
from a in arr.Select((n, i) => new { i, n })
let prev = a.i - 1
where
prev >= 0 && a.n - 1 == arr[prev] && !list.Contains(prev) && func(a.i)
select new { a.i, n = arr[a.i] };
...и пытаюсь поточнее сформулировать, где здесь торчат уши теории РСУБД. В принципе, задачку я подобрал такую, на которой обламывают зубы как раз SQL-сервера: с использованием относительного положения элементов в последовательности. Тут вот какой фокус — элементам множества можно, конечно, сопоставить отношение порядка (индекс), но тогда мы вылетим на то, что обработка последовательности сведётся (в пределе) к перепахиванию всего множества. По сути, запрос LINQ к данным апеллирует к тому же — к отбору элементов из всего множества данных. У меня задача была поставлена по-другому: я предложил отбирать данные, основываясь на их относительном положении в потенциально бесконечной последовательности. Чувствуешь, к чему клоню? Ну то есть, ту же первую задачу можно решить на yield return:
static IEnumerable<int> sample1b(IEnumerable<int> arr)
{
bool first = true;
int prev = 0;
foreach (int i in arr)
{
if (first)
{
first = false;
prev = i;
}
else if (i - prev == 1)
{
yield return i;
first = true;
}
else prev = i;
}
}
Можно это как-то сделать средствами LINQ?
Я знаю только две бесконечные вещи — Вселенную и человеческую глупость, и я не совсем уверен насчёт Вселенной. (c) А. Эйнштейн
P.S.: Винодельческие провинции — это есть рулез!
Здравствуйте, Lloyd, Вы писали:
ГВ>>Хорошо, но не надёжно из-за "Enumerable.Range(1, arr.Length — 1)" — свалится при arr.Length == 0; L>Enumerable.Range(0, arr.Length).Skip(1)
Ясно.
ГВ>>Компактно, но не правильно. Я имел в виду соседей выбранного элемента. В прочем, я не совсем удачно сформулировал вторую задачу. L>Это еще проще.
Я знаю только две бесконечные вещи — Вселенную и человеческую глупость, и я не совсем уверен насчёт Вселенной. (c) А. Эйнштейн
P.S.: Винодельческие провинции — это есть рулез!
Здравствуйте, Геннадий Васильев, Вы писали:
ГВ>...и пытаюсь поточнее сформулировать, где здесь торчат уши теории РСУБД. В принципе, задачку я подобрал такую, на которой обламывают зубы как раз SQL-сервера: с использованием относительного положения элементов в последовательности.
Ты совершенно правильно все сделал. Неотъемлемое свойство, и слабое место реляционной модели (превращается в силу в ряде контекстов) — отсутствие в этой модели порядка элементов. Кортежи принципиально неупорядоченны. Точка. И твой, и мои примеры с БД time series это свойство эксплуатируют.
Все, что тебе нужно, чтобы окончательно выбить у них почву из под ног — убрать из задачи регулярный индекс. Вот тогда им попа. Они просто не смогут выразить это одним запросом. Сделай так, что в качестве индекса идет, например, время, а не номер элемента.
Под рукой компилятора нет. Идея в том, что из первого запроса выбрасываем селект и получаем массив индексов в arr. Далее — аналогично второму запросу, но в левой части (перед where) стоит Enumerable.Range(1, arr.Length), а условие остается таким же.
G>У тебя в целом код лучше, чем у IT. Первый пример, правда, по очевидной причине проигрывает циклу (ибо ты изображаешь цикл), но давай понадеемся на второй.
Первый пример сводим к циклу, а не изображает его.
Он выигрывает перед циклом, т.к. цикла пока никто не показал.
Здравствуйте, Геннадий Васильев, Вы писали:
ГВ>>>Компактно, но не правильно. Я имел в виду соседей выбранного элемента. В прочем, я не совсем удачно сформулировал вторую задачу. L>>Это еще проще.
ГВ>Кстати, а как?
ГВ>Вообще, давай продолжим здесь
Здравствуйте, Gaperton, Вы писали:
ГВ>>...и пытаюсь поточнее сформулировать, где здесь торчат уши теории РСУБД. В принципе, задачку я подобрал такую, на которой обламывают зубы как раз SQL-сервера: с использованием относительного положения элементов в последовательности.
G>Ты совершенно правильно все сделал. Неотъемлемое свойство, и слабое место реляционной модели (превращается в силу в ряде контекстов) — отсутствие в этой модели порядка элементов. Кортежи принципиально неупорядоченны. Точка. И твой, и мои примеры с БД time series это свойство эксплуатируют.
Угу-угу. В том-то и дело, что в ряде контекстов — да, превращается. А когда нужно перепахать много гиг в один проход — превращается в наказание. Ну или как вариант — работа в реальном времени с временными отсчётами.
G>Все, что тебе нужно, чтобы окончательно выбить у них почву из под ног — убрать из задачи регулярный индекс. Вот тогда им попа. Они просто не смогут выразить это одним запросом. Сделай так, что в качестве индекса идет, например, время, а не номер элемента.
Обрати внимание на последний пример в моём постинге, там как раз не используется индекс. В принципе, foreach можно заменить на вот такую конструкцию:
static IEnumerable<int> sample1c(IEnumerable<int> arr)
{
bool first = true;
int prev = 0;
IEnumerator<int> ie = arr.GetEnumerator();
if (ie.MoveNext())
for (int i = ie.Current; ; i = ie.Current)
{
if (first)
first = false;
else if (i - prev == 1)
{
yield return i;
first = true;
}
prev = i;
if (!ie.MoveNext())
break;
}
}
Получаем автомат, работающий на бесконечной последовательности и никакого регулярного индекса. Просто не хотелось усложнять — вводить ещё сравнения времени, дополнительные фишки какие-то. В общем-то, заморочки с позиционным счислением пример, по-моему, иллюстрирует достаточно хорошо.
Я знаю только две бесконечные вещи — Вселенную и человеческую глупость, и я не совсем уверен насчёт Вселенной. (c) А. Эйнштейн
P.S.: Винодельческие провинции — это есть рулез!
.
L>Сейчас не могу. Но бесконесность последовательности — не препятствие, просто код несколько сложнее будет.
Вот как раз его очень любопытно было бы посмотреть.
Я знаю только две бесконечные вещи — Вселенную и человеческую глупость, и я не совсем уверен насчёт Вселенной. (c) А. Эйнштейн
P.S.: Винодельческие провинции — это есть рулез!
Здравствуйте, Геннадий Васильев, Вы писали:
ГВ>Нет, первая задача правильно решена. Выделенное значит, что ты ошибся в решении второй задачи на пару с Lloyd.
А это уже гон. Постановка была неправильной, а не решение.
Здравствуйте, Lloyd, Вы писали:
ГВ>>Нет, первая задача правильно решена. Выделенное значит, что ты ошибся в решении второй задачи на пару с Lloyd. L>А это уже гон. Постановка была неправильной, а не решение.
Ну не начинай. Я уже сказал, что не совсем внятно поставил задачу, там могли быть разночтения. И давай замнём на этом для ясности.
Я знаю только две бесконечные вещи — Вселенную и человеческую глупость, и я не совсем уверен насчёт Вселенной. (c) А. Эйнштейн
P.S.: Винодельческие провинции — это есть рулез!
Здравствуйте, Геннадий Васильев, Вы писали:
ГВ>>>Нет, первая задача правильно решена. Выделенное значит, что ты ошибся в решении второй задачи на пару с Lloyd. L>>А это уже гон. Постановка была неправильной, а не решение.
ГВ>Ну не начинай. Я уже сказал, что не совсем внятно поставил задачу, там могли быть разночтения. И давай замнём на этом для ясности.
То есть ты ошибся с формулоировкой? Раз так, ок, замнем.
. L>Сейчас не могу. Но бесконесность последовательности — не препятствие, просто код несколько сложнее будет.
Никто никуда не торопится.
Я знаю только две бесконечные вещи — Вселенную и человеческую глупость, и я не совсем уверен насчёт Вселенной. (c) А. Эйнштейн
P.S.: Винодельческие провинции — это есть рулез!
Здравствуйте, Gaperton, Вы писали:
G>Сделай так, что в качестве индекса идет, например, время, а не номер элемента.
Вообще, знаешь, ты прав, пожалуй. Можно ввести требование, например, "отбирать запись, отстоящую от заданной не более, чем на -30 минут", или вообще — связанную с какой-то отдельной меткой события.
Есть ещё вариант — например, построить дерево по линейной последовательности в один проход.
Я знаю только две бесконечные вещи — Вселенную и человеческую глупость, и я не совсем уверен насчёт Вселенной. (c) А. Эйнштейн
P.S.: Винодельческие провинции — это есть рулез!
Здравствуйте, Геннадий Васильев, Вы писали:
G>>Сделай так, что в качестве индекса идет, например, время, а не номер элемента.
ГВ>Вообще, знаешь, ты прав, пожалуй. Можно ввести требование, например, "отбирать запись, отстоящую от заданной не более, чем на -30 минут", или вообще — связанную с какой-то отдельной меткой события.
Да, именно это я и имел в виду.
Замечу — ты все понял, без уточнения понятий "индекс" и "время" .
Здравствуйте, Gaperton, Вы писали:
ГВ>>Вообще, знаешь, ты прав, пожалуй. Можно ввести требование, например, "отбирать запись, отстоящую от заданной не более, чем на -30 минут", или вообще — связанную с какой-то отдельной меткой события. G>Да, именно это я и имел в виду.
G>Замечу — ты все понял, без уточнения понятий "индекс" и "время" .
Дык. Шишки на лбу не пропьёшь.
Я знаю только две бесконечные вещи — Вселенную и человеческую глупость, и я не совсем уверен насчёт Вселенной. (c) А. Эйнштейн
P.S.: Винодельческие провинции — это есть рулез!
Здравствуйте, Lloyd, Вы писали:
L>Первый пример сводим к циклу, а не изображает его. L>Он выигрывает перед циклом, т.к. цикла пока никто не показал.
Ок, если честно — я не показывал цикла, ибо считал решение с циклом слишком простым и очевидным. Давай я и покажу чуть позже. Попробую на Go. Этот язык мне так же мало знаком, как и тебе, так что вставлю комменты.
Здравствуйте, Lloyd, Вы писали:
L>Первый пример сводим к циклу, а не изображает его. L>Он выигрывает перед циклом, т.к. цикла пока никто не показал.
func ( x []int ) p( i int ) bool {
return i > 1 && x[ i - 1 ] == x[ i ] + 1
}
func gena_1( x []int ) []int {
res := vector.NewIntVector(0)
for i, val = range x {
if x.p( i ) && !x.p( i - 1 ) {
res.Push( val )
}
}
return res.Data()
}
Лобовое решение, завернутое в отдельную функцию. Вся работа делается в 4-х строках кода. Просто, понятно, и очевидно.
Этот цикл в три строки элементарно записывается через array comprehension. Примерно так:
{ x[i] | i <- [2..len(x)-1], x.p(i) & !x.p(i-1) }
Что безусловно выглядит более изящно, но по сути своей — совершенно то же самое, и соответствует варианту с циклом один-в-один. Примерно так, с небольшими поправками на синтаксис, это будет выглядеть в Haskell, Clean, и Erlang. В первых двух задача вообще решается в две строки кода.
Ваши примеры с Linq — ужасны, и проигрывают компрехеншнсам. При этом, в них по своей сути нет ничего, что не могло бы быть сделано при помощи простых ФВП и циклов. Никакой принципиальной разницы, и преимущества нет. Только закрученный на ровном месте код, и все.
Подозреваю, что и с вашим Linq эту задачу можно решить так же. В противном случае он бы вообще никуда не годился.