Выполнение определенных действий для всех элементов в Счетном <T>

Таким образом, вы можете сделать что-то вроде этого,

def index
  @articles = Article.all
  @some_articles = @articles.select {|article| article.title == 'SOME STRING'}
end

, а затем, по вашему мнению, вы можете создать второй цикл

<% @articles.each do |article| %> <%= article.title %> <%= article.text %> <%= link_to 'Show', article_path(article) %> <% end %>
<% @some_articles.each do |some_article| %> <%= some_article.title %> <%= some_article.text %> <%= link_to 'Show', article_path(some_article) %> <% end %>

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

Вы должны проверить эту документацию для получения дополнительной информации о запросах к базе данных в rails, и я не знаю, видели ли вы Руководство по Ruby on Rails , которое является отличным началом место и может помочь вам (не уверен, если вы прочитали его еще)

47
задан MicroVirus 13 May 2016 в 17:32
поделиться

7 ответов

Quick-easy для получения этого:

Names.ToList().ForEach(e => ...);
57
ответ дан Jay Bazuzi 26 November 2019 в 19:32
поделиться

Вы ищете когда-либо неуловимый ForEach, который в настоящее время только существует на универсальном наборе Списка. Существует много дискуссий онлайн о том, должна ли Microsoft или не должна добавлять это как метод LINQ. В настоящее время Вы имеете к самокрутке:

public static void ForEach<T>(this IEnumerable<T> value, Action<T> action)
{
  foreach (T item in value)
  {
    action(item);
  }
}

, В то время как All() метод обеспечивает подобные способности, это - пример использования, для выполнения теста предиката на каждом объекте, а не действии. Конечно, это может быть убеждено выполнить другие задачи, но это несколько изменяет семантику и мешало бы другим интерпретировать Ваш код (т.е. это использование All() для теста предиката или действия?).

18
ответ дан Jeff Yates 26 November 2019 в 19:32
поделиться

<глоток> Правовая оговорка: Это сообщение больше не напоминает мой исходный ответ, а скорее включает опыт этих приблизительно семи лет, который я получил с тех пор. Я сделал редактирование, потому что это - высоко просматриваемый вопрос, и ни один из существующих ответов действительно не касался всех углов. Если Вы хотите видеть мой исходный ответ, это доступно в история пересмотра для этого сообщения .

<час>

первой вещью понять вот являются операции C# linq как Select(), All(), Where(), и т.д., имейте их корни в [1 136] функциональное программирование . Идея состояла в том, чтобы принести некоторые более полезные и доступные части функционального программирования к миру .NET. Это важно, потому что ключевой принцип функционального программирования - чтобы операции были свободны от побочных эффектов. Трудно преуменьшить это. Однако в случае ForEach() / each(), побочные эффекты являются всей целью операции. Добавление each() или ForEach() не недалеко от объема функционального программирования других linq операторов, но в прямой оппозиции им.

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

Eric Lippert, который был на команде разработчиков C# в то время, может помочь нам здесь. Он рекомендует использовать традиционное foreach цикл:

[ForEach ()] добавляет нулевое новое представительное питание к языку. Выполнение этого позволяет Вам переписать этот совершенно код разъединения:

foreach(Foo foo in foos){ statement involving foo; }

в этот код:

foos.ForEach(foo=>{ statement involving foo; });

Его точка, когда Вы пристально смотрите на свои опции синтаксиса, Вы не получаете ничего нового от ForEach() расширение по сравнению с традиционным foreach цикл. Я частично не соглашаюсь. Предположите, что у Вас есть это:

 foreach(var item in Some.Long(and => possibly)
                         .Complicated(set => ofLINQ)
                         .Expression(to => evaluate)
 {
     // now do something
 } 

Этот код запутывает значение, потому что это отделяется foreach ключевое слово от операций в цикле. Это также перечисляет команду цикла, предшествующую к операциям, которые определяют последовательность, на которую воздействует цикл. Чувствует себя намного более естественным хотеть начать те операции, на первом месте и затем имеют команду цикла в конец из определения запроса. Кроме того, код просто ужасен. Кажется, что было бы намного более хорошо смочь записать это:

Some.Long(and => possibly)
   .Complicated(set => ofLINQ)
   .Expression(to => evaluate)
   .ForEach(item => 
{
    // now do something
});

Однако даже здесь, я в конечном счете возвратился к точке зрения Eric. Я понял, что код как Вы видит выше, вызывает для дополнительной переменной. Если у Вас есть сложный набор выражений LINQ как этот, можно добавить ценную информацию к коду первым присвоением результата выражения LINQ к новой переменной:

var queryForSomeThing = Some.Long(and => possibly)
                        .Complicated(set => ofLINQ)
                        .Expressions(to => evaluate);
foreach(var item in queryForSomeThing)
{
    // now do something
}

Этот код чувствует себя более естественным. Это возвращается foreach ключевое слово рядом с остальной частью цикла, и после определения запроса. Больше всего имя переменной может добавить новую информацию, которая будет полезна будущим программистам, пытающимся понять цель запроса LINQ. Снова, мы видим желаемое ForEach(), оператор действительно не добавил нового выразительного питания к языку.

Однако мы все еще пропускаем две функции гипотетического ForEach() дополнительный метод:

  1. Это не компонуемо. Я не могу добавить еще [1 120] или GroupBy() или OrderBy() после foreach цикл, встроенный с остальной частью кода, не создавая новый оператор.
  2. Это не лениво. Эти операции сразу происходят. Это не позволяет мне, скажем, иметь форму, где пользователь выбирает операцию в качестве одного поля на большем экране, который не действуется на то, пока пользователь не нажимает кнопку. Эта форма могла бы позволить пользователю передумать прежде, чем выполнить команду. Это совершенно нормально ( легкий даже) с запросом LINQ, но не как простое с foreach.

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

Select() соответствия вид преобразования или проекции, описанной обоими из примеров выше. Следует иметь в виду, тем не менее, что я все еще постарался бы не создавать побочные эффекты. Вызов к [1 128] должен возвратить или новые объекты или проекции из оригиналов. Этому можно иногда помогать с помощью анонимного текстового или динамического объекта (если и только если необходимый). При необходимости в результатах для сохранения в, скажем, исходной переменной списка, можно всегда называть .ToList() и присваивать ее назад исходной переменной. Я добавлю здесь, что предпочитаю работать с [1 130] переменные как можно больше по более конкретным типам.

myList = myList.Select(item => new SomeType(item.value1, item.value2 *4)).ToList();

, Таким образом:

  1. Просто палка с [1 131] большую часть времени.
  2. , Когда foreach действительно не сделает (который, вероятно, не является так часто, как Вы думаете), используйте Select()
  3. , Когда необходимо использовать Select(), можно все еще обычно избегать (видимых программой) побочных эффектов, возможно путем проектирования к анонимному типу.
12
ответ дан Joel Coehoorn 26 November 2019 в 19:32
поделиться

К сожалению, нет никакого встроенного способа сделать это в текущей версии LINQ. Команда платформы забыла добавлять.ForEach дополнительный метод. Существует хорошая дискуссия об этом продолжении прямо сейчас на следующем блоге.

http://blogs.msdn.com/kirillosenkov/archive/2009/01/31/foreach.aspx

довольно легко добавить то все же.

public static void ForEach<T>(this IEnumerable<T> enumerable, Action<T> action) {
  foreach ( var cur in enumerable ) {
    action(cur);
  }
}
6
ответ дан JaredPar 26 November 2019 в 19:32
поделиться

Вы не можете сделать этого сразу же с LINQ и IEnumerable - необходимо или реализовать собственный дополнительный метод, или бросить перечисление к массиву с LINQ и затем назвать Массив. ForEach ():

Array.ForEach(MyCollection.ToArray(), x => x.YourMethod());

Обратите внимание на то, что из-за пути оценивают работу типов и структур, если набор будет иметь тип значения, и Вы изменяете элементы набора этот путь, то это не будет иметь никакого эффекта на элементы исходного набора.

5
ответ дан Tamas Czinege 26 November 2019 в 19:32
поделиться

Поскольку LINQ разработан, чтобы быть функцией запроса и не функцией обновления, Вы не найдете расширение, которое выполняет методы на IEnumerable< T> потому что это позволило бы Вам выполнять метод (потенциально с побочными эффектами). В этом случае можно также просто придерживаться с

foreach (имя строки на Имена)
Консоль. WriteLine (имя);

2
ответ дан Peter Morris 26 November 2019 в 19:32
поделиться

Существует метод ForEach прочь Списка. Вы могли преобразовать Счетное, чтобы Перечислить путем называния.ToList () методом и затем отменить метод ForEach этого.

, С другой стороны, я услышал о людях, определяющих их собственный метод ForEach прочь IEnumerable. Это может быть выполнено путем важного вызова метода ForEach, но вместо этого обертывания его в дополнительном методе:

public static class IEnumerableExtensions
{
    public static IEnumerable<T> ForEach<T>(this IEnumerable<T> _this, Action<T> del)
    {
        List<T> list = _this.ToList();
        list.ForEach(del);
        return list;
    }
}
0
ответ дан David Morton 26 November 2019 в 19:32
поделиться
Другие вопросы по тегам:

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