Перебор свойств объекта в IList без цикла

Рассмотрим следующую ситуацию:

public class Employee
{
    public string Name {get; set}
    public string Email {get; set}
}

public class EnployeeGroup
{
    //List of employees in marketting
    public IList<Employee> MarkettingEmployees{ get; }

    //List of employees in sales
    public IList<Employee> SalesEmployees{ get; }
}

private EnployeeGroup GroupA;

int MarkettingCount;
string MarkettingNames;

MarkettingCount = GroupA.MarkettingEmployees.Count; //assigns MarkettingCount=5, this will always be 5-10 employees
MarkettingNames = <**how can i join all the GroupA.MarkettingEmployees.Name into a comma separated string?** >

//I tried a loop:
foreach(Employee MktEmployee in GroupA.MarkettingEmployees)
{
    MarkettingNames += MktEmployee.Name + ", ";
}

Цикл работает, но я хочу знать:

  1. Является ли Looping наиболее эффективным / элегантным способом сделать это? Если нет, то каковы лучшие альтернативы? Я попробовал string.join, но не смог заставить его работать..
  2. Я хочу избежать Linq..

4 ответа

Решение

Вам нужно немного LINQ, нравится вам это или нет;)

MarkettingNames = string.Join(", ", GroupA.MarkettingEmployees.Select(e => e.Name));

С практической точки зрения, нет разумного аргумента для избежания цикла. Итерации трудны для любого универсального языка программирования.

Использование LINQ элегантно в простых случаях. Опять же, нет веской причины избегать этого как такового.

Если вы ищете неясное академическое решение, всегда есть хвостовая рекурсия. Тем не менее, ваша структура данных должна быть адаптирована для этого. Обратите внимание, что даже если вы используете его, умный компилятор обнаружит его и оптимизирует в цикле. Шансы на тебя!

В качестве альтернативы вы можете использовать StringBuilder с Append, вместо создания новой строки на каждой итерации

Это было бы намного эффективнее (см. Предостережение ниже):

var stringBuilder = new StringBuilder();
foreach (Employee MktEmployee in GroupA.MarkettingEmployees)
{
    stringBuilder.Append(MktEmployee.Name + ", ");
}

Тогда это:

foreach(Employee MktEmployee in GroupA.MarkettingEmployees)
{
    MarkettingNames += MktEmployee.Name + ", ";
}

Изменить: Если бы у вас было большое количество сотрудников, это было бы гораздо более эффективным. Тем не менее, тривиальный цикл из 5-10 фактически немного менее эффективен.

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

Кроме того, если вы хотите использовать явный циклический подход, вероятно, лучше обрезать последний ", " используя что-то вроде:

myString = myString.Trim().TrimEnd(',');

Статья ниже объясняет, когда вы должны использовать StringBuilder объединить строки.

Короче говоря, в подходе, который вы используете: конкатенация каждый раз создает новую строку, которая, очевидно, пожирает много памяти. Вам также необходимо скопировать все данные из существующей строки MarkettingNames к новой строке добавляется еще одна MktEmployee.Name + ", ",

Спасибо, Джон Скит: http://www.yoda.arachsys.com/csharp/stringbuilder.html

Другие вопросы по тегам