2014-02-21 5 views
0

У меня есть массив пользователей и отдел групп в соответствии с:наименее дорогой способ для обхода массива данных

**users:** 
Array 
(
    [0] => Array 
     (
      [Name] => John 
      [City] => New York 
     ) 

    [1] => Array 
     (
      [Name] => Amy 
      [City] => San Francisco 
     ) 
    [3] => Array 
     (
      [Name] => Jacob 
      [City] => Seattle 
     ) 
) 

**departmentgroups** 
Array 
(
    [0] => stdClass Object 
     (
      [name] => HR 
      [member] => Array 
       (
        [0] => John 
        [1] => Jake 
        [2] => Amy 
        [3] => Mark 
       ) 

     ) 

    [1] => stdClass Object 
     (
      [name] => Finance 
      [member] => Array 
       (
        [0] => Jacob 
        [1] => John 
        [2] => Amy 
        [3] => David 
        [4] => Ramone 
       ) 

     ) 
) 

Мне нужно напечатать все пользователь в массиве пользователей вместе с их отделами путем обхода через эти 2 массивов. Итак, моя первоначальная реакция состоит в том, чтобы прокрутить массив пользователей, а затем для каждого пользователя, провести цикл через массив отделов и вернуть название отдела. Если они принадлежат нескольким отделам, массив отдела будет возвращен.

Я обнаружил, что этот вид переезда очень дорог и занимает некоторое время, если у меня есть список из 20000 пользователей и 30000 групп отделов.

Есть ли быстрый способ сделать это вместо циклов for?

+1

это эти данные уже в дБ? похоже, было бы лучше создать запрос, который группирует их –

+0

нет .. данные находятся в массивах. Он исходит из API – Jake

+0

также, святой дерьмо, 30000 отделов? действительно? Я не знал, что такой бизнес может существовать с таким количеством отделов –

ответ

0

Проверьте функцию array_merge_recursive. Возможно, вам потребуется увеличить использование памяти в настройках php.ini.

1

Простой ответ: нет эффективного способа. Не стоит читать эту статью, я просто написал, я просто не хотел, чтобы его выбросить;)

Big O нотация

Ну, я определенно был не самый умный студент вернулся в университет, но то, что Я помню, что у нас был «Big O Notation», когда дело дошло до сложности.

Итак, давайте попробуем обсудить, что вы пытаетесь сделать. У меня есть один массив Users размера n и другой массив Departments размера m.

Что вы хотите - это связь между Users и Departmens, и, как вы заявили, вам «нужно распечатать всех пользователей в массиве пользователей вместе со своими подразделениями». Таким образом, у вас есть хотя бы сложность n (так как вам нужны все пользователи в массиве Users).

Теперь мы рассмотрим массив departments. Как мы можем видеть из вашего примера, Джон в HR, а также в Финансах. Таким образом, пользователь может работать для нескольких отделов. Это означает, какой позор, что нам всегда нужно перебирать весь departments, чтобы убедиться, что мы не пропустили один из отделов, на котором работает пользователь. Мы помним, что массив departments имеет размер m.

Итак, для каждого пользователя мы должны пройти через m элементов в departments. Для первого пользователя м элементов для второго пользователя м элементов и т. Д. Поскольку у нас есть n пользователей, наша сложность O(n*m).

Это, как вы могли заметить, никогда не было эффективным! И в мире нет функции массива, даже на другом языке, что могло бы сделать ее более эффективной.

Или, конечно, я не знаю всех ваших прецедентов. Если вам нужно составить этот список только один раз, я предлагаю вам сделать это таким образом. Каждая «оптимизация» может привести к ошибкам и сделать ваш код более сложным для отладки.

Если вы не знакомы со сложностью в Big O нотации, подумайте об этом следующее, я называю это

База способ

У вас есть одна таблица со всеми пользователями и одну таблицу со всеми ведомства. Поскольку один пользователь может находиться во многих отделах, а один отдел может иметь много пользователей, у вас будет таблица соединений, например user_id | department_id, назовем ее users_to_departments. Конечно, вы можете подумать, что ваша таблица users_to_departments будет определенно меньше, чем n*m. Но чтобы заполнить его, сначала нужно добавить всех пользователей в таблицу users, а затем, заполнив таблицу departments, вам нужно будет найти идентификатор пользователя в users.

Но остановитесь, вы сказали, что имена пользователей уникальны! Поэтому используйте это поле «имя» в качестве того, что я назвал user_id, и здесь мы идем, мы спасли нас от поиска каждого пользователя в таблице users.

Теперь вы можете сделать простой SELECT * FROM users_to_departments ud JOIN users u ON u.id = ud.user_id JOIN departments d ON d.id = ud.department_id ORDER BY ud.user_id, ud.department_id, чтобы получить список. Просто помните, что пользователь будет в списке x раз, когда в x отделах.

Заключение

И, если вы спросите меня, я не думаю, что это будет быстрее, так как вы должны передать все данные из веб-сервиса в базе данных, запрос из базы данных и трансформировать свой ответ. Для меня это звучит только более склонно к ошибкам и даже не более эффективно.

Смежные вопросы