-2

I've been searching for this and can't find it, though it's hard to put in to words so I apologize if it's covered elsewhere.

I have an API call I make that gives me this. This is shifts worked on a given date and there is an array for each shift. This is what one looks like.

$lastMon = array{
       date => $date
       hours => 8
       worker => mjones
       etc
       }

Now I want to take the recruiter value and the hours value and create another array that looks like this

$lastMonData = array{
       key for each $lastMon->recruiter => sum of all $lastMon->hours where recruiter is unique
       total += $lastMon->hours
       }

Basically, I have a bunch of shifts I extract from this system and turn it in to arrays and insert some keys I pull from other parts of the system. I then need an array by date that contains the total hours worked for all the shifts that day, and then a key for each unique name in the recruiter key that adds up the hours mentioned in the same array. I hope this makes sense.

EDIT:

Here is an example

SimpleXMLElement Object
(
    [orderId] => 4000262
    [status] => filled
    [shiftStartTime] => 2018-12-10T07:30:00
    [shiftEndTime] => 2018-12-10T12:30:00
    [tempId] => 80231
    [firstName] => SimpleXMLElement Object
        (
        )

    [lastName] => SimpleXMLElement Object
        (
        )

    [clientId] => 42642
    [clientName] => SimpleXMLElement Object
        (
        )

    [regionName] => SimpleXMLElement Object
        (
        )

    [orderSpecialty] => School
    [orderCertification] => RN
    [floor] => SimpleXMLElement Object
        (
        )

    [shiftNumber] => 1
    [note] => SimpleXMLElement Object
        (
        )

    [payrollNumber] => SimpleXMLElement Object
        (
        )

    [lessLunchMin] => SimpleXMLElement Object
        (
        )

    [dateTimeCreated] => 2018-08-17T09:33:43
    [takenBy] => 592
    [bookedByUserId] => 592
    [orderTypeId] => 1
    [orderType] => SimpleXMLElement Object
        (
        )

    [city] => Holmdel
    [state] => NJ
    [zipCode] => 07733
    [orderSourceID] => SimpleXMLElement Object
        (
        )

    [orderSourceName] => SimpleXMLElement Object
        (
        )

    [lt_orderID] => 13643
    [dateTimeModified] => 2018-08-17T09:33:43
    [recruiter] => John Smith
    [hours] => 05
)
SimpleXMLElement Object
(
    [orderId] => 4002473
    [status] => filled
    [shiftStartTime] => 2018-12-10T09:00:00
    [shiftEndTime] => 2018-12-10T13:30:00
    [tempId] => 1397353
    [firstName] => SimpleXMLElement Object
        (
        )

    [lastName] => SimpleXMLElement Object
        (
        )

    [clientId] => 47597
    [clientName] => SimpleXMLElement Object
        (
        )

    [regionName] => SimpleXMLElement Object
        (
        )

    [orderSpecialty] => School
    [orderCertification] => RN
    [floor] => SimpleXMLElement Object
        (
        )

    [shiftNumber] => 1
    [note] => SimpleXMLElement Object
        (
        )

    [payrollNumber] => SimpleXMLElement Object
        (
        )

    [lessLunchMin] => SimpleXMLElement Object
        (
        )

    [dateTimeCreated] => 2018-08-20T08:53:23
    [takenBy] => 592
    [bookedByUserId] => 592
    [orderTypeId] => 1
    [orderType] => SimpleXMLElement Object
        (
        )

    [city] => Tinton Falls
    [state] => NJ
    [zipCode] => 07701
    [orderSourceID] => SimpleXMLElement Object
        (
        )

    [orderSourceName] => SimpleXMLElement Object
        (
        )

    [lt_orderID] => 0
    [dateTimeModified] => 2018-08-20T10:05:33
    [recruiter] => Mike Jones
    [hours] => 04
)

I need to take the recruiter value and make those in to keys in a new array. Some repeat, so I would only want to take the unique ones. Then, the hours value in this array would be the value for the recruiter name key in the new array.

So this would then look like

$lastMon = array{
      Mike Jones => 4
      John Smith => 5
      Total => 9
}
4
  • What have you tried so far and what is your specific problem? What's wrong with looping trough your first array and creating the second one during that? Commented Dec 19, 2018 at 0:34
  • 1
    I think I understand what you're asking, but I need to see a real example of your input data to explain how you can do it. In general you will get much better results asking questions here if the examples you provide are either real parseable PHP code or at least var_dump/print_r output. Commented Dec 19, 2018 at 0:47
  • Can you post your expected output. Also, there is no 'recruiter' value. What would it be? Commented Dec 19, 2018 at 0:53
  • I will post what I'm looking at. I changed recruiter to worker too. Sorry about that. But what I have is values from another arrays keys. I need the unique values there, which are names, to then be keys in a new array with their values being a sum of the hours key from the original array for each name. Then I also sum all the hours together across all names. But I will post the entire original array in a minute. Commented Dec 19, 2018 at 14:43

1 Answer 1

0

You can use array-reduce to aggregate the recruiter hours:

$lastMon = array(array("recruiter" => "AAA", "hours" => 4), array("recruiter" => "BBB", "hours" => 5), array("recruiter" => "AAA", "hours" => 3));

function reduceHours($carry, $item)
{
    if (!array_key_exists($item["recruiter"], $carry))
        $carry[$item["recruiter"]] = 0;
    $carry[$item["recruiter"]] += $item["hours"];
    return $carry;
}


$lastMonData = array_reduce($lastMon, "reduceHours", array());

This will output:

Array
(
    [AAA] => 7
    [BBB] => 5
)

Edited

Now that you added more data I can give you more detailed answer:

$str = '<xml><shifts><recruiter>John Smith</recruiter><hours>05</hours></shifts><shifts><recruiter>Mike Jones</recruiter><hours>04</hours></shifts><shifts><recruiter>John Smith</recruiter><hours>08</hours></shifts></xml>';
$arr = json_decode(json_encode((array) simplexml_load_string($str)), 1);

function sum($carry, $item) { return $carry + $item;}
function reduceHours($carry, $item)
{
    if (!array_key_exists($item["recruiter"], $carry))
        $carry[$item["recruiter"]] = 0;
    $carry[$item["recruiter"]] += $item["hours"];
    return $carry;
}

$lastMonData = array_reduce($arr["shifts"], "reduceHours", array());
$lastMonData["total"] = array_reduce($lastMonData, "sum");

Converting xml object to array is from here.

This will give output for $lastMonData:

Array
(
    [John Smith] => 13
    [Mike Jones] => 4
    [total] => 17
)

I know the sum of total can be done in other ways but I tried to keep the example of using array_reduce.

Sign up to request clarification or add additional context in comments.

7 Comments

This is pretty much exactly what I'm looking for. I just can't get it to work. Sorry yesterday was a long day, but $lastMon is from a simplexml_load_string so it's an object not an array. How could I change that to account for it? But that's what I want it to do is combine the recruiter key values so there isn't any duplicates, and then combine the hours values where the recruiter repeats.
You rock man Array ( [Gloria M] => 13 [Shana A] => 3 [Cynthia W] => 14 [Tony C] => 4 [Alexandra C] => 5 [Sarah D] => 12 [Lindsey S] => 4 [Casi D] => 7 [Salina T] => 4 [Madeline S] => 4 [Max M] => 7 [Jeanine S] => 16 [Michael B] => 2 [Gretchen D] => 3 [total] => 98 )
So, this doesn't 100% work actually. Since it's a date time it doesn't add up properly. I'm trying to find the answer, but I figured I would ask you. I end up just a bit off because with += it's trying to treat the "hours" as strings but it's a datetime. I don't know how to adjust the function to use the "add" date interval function?
In your question the hours where strings and we add them as integer (PHP will understand they are number). What do you mean by datatime? I didn't use the shiftStartTime key. If you want to calculate the hours dynamically you can use this
You're absolutely right, it's an int. So, what's happening is it's being added incorrectly. All of the times are either top of the hour or 15 minutes intervals. However, I'm ending up with really weird times. I put %i in the format to see the minutes and this is what I get. Would it be from serializing and unserializing it? Name";d:165.5;s:15:"Name";d:199.20000000000002;s:11:"Name";d:203.15000000000003;s:13:"Name";d:93.6;s:13:"Name";d:16.6;s:0:"";i:0;s:16:"Name";d:141.64999999999998
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.