За последние 24 часа нас посетили 17793 программиста и 1652 робота. Сейчас ищут 1562 программиста ...

Массивы и коллекции.

Тема в разделе "Решения, алгоритмы", создана пользователем Umberto, 9 сен 2013.

  1. Umberto

    Umberto Новичок

    С нами с:
    9 сен 2013
    Сообщения:
    4
    Симпатии:
    0
    Добрый день. Стоит следующая задача(условия упрощу, чтобы попытаться верно донести информацию):
    На вход дан CSV файл, из которого мы выдираем:
    row[0],row[1],row[2];
    row[0] - Фамилия (Бывает, что они дублируются);
    row[1] - Фамилия второго работника(Работают в группе);
    row[2] - Вид работ (Названия разные, но выходит две классификации: Подключение и Ремонт );
    На выходе мне нужно получить следующее:
    Фамилия |Ремонтных_работ|Подключений
    Иванов | 10 | 5
    Петров | 7 | 11

    До этого работал с Java, и там бы решил данную задачу с помощью коллекций. Гуглил, но не смог найти collection framework на php.

    Задачу решил с помощью идиотского алгоритма, трех временных массивов и т.д.
    Хотелось бы увидеть ваше решение, дабы я не пошел по "неправильному пути".ъ
    Благодарю.
     
  2. igordata

    igordata Суперстар
    Команда форума Модератор

    С нами с:
    18 мар 2010
    Сообщения:
    32.408
    Симпатии:
    1.768
    надо собрать статистику по обеим фамилиям?
     
  3. Umberto

    Umberto Новичок

    С нами с:
    9 сен 2013
    Сообщения:
    4
    Симпатии:
    0
    Да, по обеим.
     
  4. runcore

    runcore Старожил

    С нами с:
    12 окт 2012
    Сообщения:
    3.625
    Симпатии:
    158
    Код (PHP):
    1. $in = array(  array('Иванов', 'Петров', 'Подключение'),
    2.   array('Петров', 'Сидоров','Ремонт'),
    3.   array('Сидоров','Сидоров','Ремонт'),
    4.   array('Иванов', 'Петров', 'Подключение'), );
    5. $out=array();
    6. foreach($in as $row) {
    7.   if (!isset($out[$row[0]][$row[2]])) { $out[$row[0]][$row[2]] = 0; }
    8.   if (!isset($out[$row[1]][$row[2]])) { $out[$row[1]][$row[2]] = 0; }
    9.   $out[$row[0]][$row[2]] += 1;
    10.   $out[$row[1]][$row[2]] += 1;
    11. }
    12. echo '<pre>'; print_r($out);
     
  5. igordata

    igordata Суперстар
    Команда форума Модератор

    С нами с:
    18 мар 2010
    Сообщения:
    32.408
    Симпатии:
    1.768
    туда же

    Код (PHP):
    1. $in = array(
    2.     array('Иванов', 'Петров', 'Ковыряние отверткой'),
    3.     array('Петров', 'Сидоров', 'Тяжка шланга'),
    4.     array('Мардадзе', 'Сидоров', 'Курение'),
    5.     array('Сидоров', 'Сидоров', 'Стучанье молотком'),
    6.     array('Иванов', 'Петров', 'Курение'),
    7.     array('Мардадзе', 'Петров', 'Подъем на этаж'),
    8.     array('Иванов', 'Петров', 'Тяжка шланга'),
    9. );
    10. //Учитывая что пхп позволяет делать длинные ключи - сделаем ход конём
    11. $worktypes = array(
    12.     'Ковыряние отверткой' => 'Ремонт',
    13.     'Тяжка шланга' => 'Подключение',
    14.     'Курение' => 'Ремонт',
    15.     'Стучанье молотком' => 'Ремонт',
    16.     'Подъем на этаж' => 'Подключение',
    17. );
    18.  
    19.  
    20. $out = array();
    21. foreach ($in as $row) {
    22.   if (!isset($out[$row[0]][$worktypes[$row[2]]])) {
    23.     $out[$row[0]][$worktypes[$row[2]]] = 0;
    24.   }
    25.   if (!isset($out[$row[1]][$worktypes[$row[2]]])) {
    26.     $out[$row[1]][$worktypes[$row[2]]] = 0;
    27.   }
    28.   $out[$row[0]][$worktypes[$row[2]]]++;
    29.   $out[$row[1]][$worktypes[$row[2]]]++;
    30. }
    31. var_dump($out); 
     
  6. artoodetoo

    artoodetoo Суперстар
    Команда форума Модератор

    С нами с:
    11 июн 2010
    Сообщения:
    11.108
    Симпатии:
    1.243
    Адрес:
    там-сям
    это АД. для запросов есть язык SQL.

    почему бы не импортировать CSV в, скажем, SQLite и потом простым и элегантным запросом не получить нужную выборку? м?
    допустим в колонке job_fix будет 1 если это ремонт, иначе 0. аналогично колонка job_link для поключений:
    Код (Text):
    1. SELECT emp_name, SUM(job_fix), SUM(job_link)
    2. FROM jobs
    3. GROUP BY emp_name
    наверняка завтра понадобится еще какая-то выборка по тем же данным -- например ограничение по дате -- напишем еще один простой и элегантный запрос.
     
  7. Umberto

    Umberto Новичок

    С нами с:
    9 сен 2013
    Сообщения:
    4
    Симпатии:
    0
    Благодарю. Третий вариант - наиболее рациональный.
    Подошел к задаче - созданием временной таблицы)
    Всем спасибо.
     
  8. runcore

    runcore Старожил

    С нами с:
    12 окт 2012
    Сообщения:
    3.625
    Симпатии:
    158
    если планируется еще много делать хитрых выборок - загнать в бд возможно рационально.
    но в данном случае, для конкретной задачи описанной ТС - один прогон цикла, один массив. скрипт пишется за 5 мин.
    а плодить лишние сущности, парсить и перекладывать в БД, создавать временные таблицы, изучать особеннности БД, учиться писать запросы SQL... путь очень долгий - для человека который с этим не работал до этого.

    так что тут нельзя быть настолько категоричным
     
  9. artoodetoo

    artoodetoo Суперстар
    Команда форума Модератор

    С нами с:
    11 июн 2010
    Сообщения:
    11.108
    Симпатии:
    1.243
    Адрес:
    там-сям
    Только для расширения горизонтов автора: в PHP есть удобные функции array_map и array_filter. в сочетании с замыканиями они дают простой и элегантный способ изобразить из себя сервер БД :)
    Видимо на Java ты привык к подобному подходу, ну с поправкой на тотальную объектность джавы.
     
  10. igordata

    igordata Суперстар
    Команда форума Модератор

    С нами с:
    18 мар 2010
    Сообщения:
    32.408
    Симпатии:
    1.768
    временная тут зачем? о_О
     
  11. Umberto

    Umberto Новичок

    С нами с:
    9 сен 2013
    Сообщения:
    4
    Симпатии:
    0
    За функции- больше спасибо! К ним можно дописать компаратор, я этого не знал)
     
  12. Fell-x27

    Fell-x27 Суперстар
    Команда форума Модератор

    С нами с:
    25 июл 2013
    Сообщения:
    12.156
    Симпатии:
    1.770
    Адрес:
    :сердА
    придется в любом случае и чем раньше, тем лучше :)