Question

Basically i got an array with this kind of structure:

Array:

0 => {
    time: "090019"
    val: "2.444"
    qta: "292"
    dir: "up"
    param: "S"
}

1=>  {
    time: "090019"
    val: "2.442"
    qta: "938"
    dir: "dwn"
    param: "N"
}

2 =>  {
    time: "090019"
    val: "2.442"
    qta: "220"
    dir: "up"
    param: "N"
}

3 =>  {
    time: "100043"
    val: "2.44"
    qta: "220"
    dir: "dwn"
    param: "N"
}

.. so on and so forth

n =>  {
    time: "103051"
    val: "2.444"
    qta: "330"
    dir: "dwn"
    param: "N"
}

And my goal is to obtain an array with the same structure where data will be merged in a precise way.

If two ore more array values have the same time (time) and value (val) they will be: added if they had same direction (dir), and subtracted if they don't (in this case the resulting direction will be the (dir) of the higher value). The param (param) is irrelevant.

I'm quite brand new with Php and I never know how to approach when I have to solve things like that.

Hoping to be sufficiently clear, any advice will be appreciated.

EDIT:

the resulting array will be like:

0 => {
    time: "090019"
    val: "2.444"
    qta: "292"
    dir: "up"
    param: "S"
}

1 =>  {
    time: "090019"
    val: "2.442"
    qta: "718"
    dir: "dwn"
    param: "N"
}

2 =>  {
    time: "100043"
    val: "2.44"
    qta: "220"
    dir: "dwn"
    param: "N"
}


..

n =>  {
    time: "103051"
    val: "2.444"
    qta: "330"
    dir: "dwn"
    param: "N"
}
Was it helpful?

Solution

This is kind of a fun problem, so here's something that would probably work for you, out of the box :)

First, define your items:

$items = array(

    array(
        "time" => "090019",
        "val" => "2.444",
        "qta" => "292",
        "dir" => "up",
        "param" => "S",
    ),

    array(
        "time" => "090019",
        "val" => "2.442",
        "qta" => "938",
        "dir" => "dwn",
        "param" => "N",
    ),

    array(
        "time" => "090019",
        "val" => "2.442",
        "qta" => "220",
        "dir" => "up",
        "param" => "N",
    ),

    array(
        "time" => "100043",
        "val" => "2.44",
        "qta" => "220",
        "dir" => "dwn",
        "param" => "N",
    ),

);

Next, iterate through the items array once to group items together based on the same time and val:

$grouped_items = array();

foreach($items as $item) {
    $key = "{$item['time']}-{$item['val']}";

    if( empty($grouped_items[$key]) ) $group_items[$key] = array();

    $grouped_items[$key][] = $item;
}

At this point, you have an array with keys equal to time-val. Each of those is a subarray containing a list of all items matching that item-val (so you grouped together the same time/val items). Finally, you can create your merged list:

$final_items = array();

foreach($grouped_items as $item_list) {
    $final_items[] = mergeItems($item_list);
}

// merge a list of items with the same time and val
function mergeItems($items) {
    $merged_item = array(
        "time" => $items[0]['time'],
        "val" => $items[0]['val'],
        "qta" => 0,
        "dir" => null,
        "param" => $items[0]['param'],
    );

    // add or subtract qta values
    foreach($items as $item) {
        if( $item['dir'] == "up" ) {
            $merged_item["qta"] += (int) $item["qta"];
        }
        else {
            $merged_item["qta"] -= (int) $item["qta"];
        }
    }

    // set the final qta and dir value
    if( $merged_item["qta"] < 0 ) {
        $merged_item["qta"] *= -1;
        $merged_item["dir"] = "down";
    }
    else {
        $merged_item["dir"] = "up";
    }

    return $merged_item;
}

Now $final_items has your merged list.

If you paste all of this into one PHP script, it'll run and give you the output you want. If it doesn't do exactly what you want with your real data, then you forgot to mention something in your question and can probably use this example to create something that will work :)

OTHER TIPS

This is a generic answer where you can do what you want with the new qta:

$items = array([put your data here]);

for($i=0; $i < count($items); $i++) {
    for($j=0; $j < count($items); $j++) {
        // don't compare and item to itself
        if($i == $j) continue;

        // if their times and values are equal
        if( $items[$i]["time"] == $items[$j]["time"] && $items[$i]["val"] == $items[$j]["val"]) {
            // dirs are the same
            if( $items[$i]["dir"] == $items[$j]["dir"] ) {
                $newqta = $items[$i]["qta"] + $items[$j]["qta"];
                $newdir = $items[$i]["dir"];
            }
            // dirs are different
            else {
                $newqta = $items[$i]["qta"] - $items[$j]["qta"];

                if( $items[$i]["qta"] > $items[$j]["qta"] ) {
                    $newdir = $items[$i]["dir"];
                }
                else {
                    $newdir = $items[$j]["dir"];
                }
            }

            // do something with $newqta and $newdir
        }
    }
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top