2

I have an array structure that is stored in Session

edit : the number of item_id's is not definite. It maybe 1-3 items on one transaction and 2-20 items on the next.

"items": [{
    "item_id": "1",
    "item_quantity": "151"
}, {
    "item_id": "2",
    "item_quantity": "54"
}, {
    "item_id": "2",
    "item_quantity": "23"
}, {
    "item_id": "3",
    "item_quantity": "3"
}, {
    "item_id": "3",
    "item_quantity": "3"
}]

What I'm trying to achieve is to add up all item_quantity which has the same item_id

"items": [{
    "item_id": "1",
    "item_quantity": "151"
}, {
    "item_id": "2",
    "item_quantity": "77"
}, {
    "item_id": "3",
    "item_quantity": "6"
}]

This is what I have tried so far, but I'm not getting the desired result

Controller

public function Save() {
    if (Input::has('addItem')) {
        if (Session::has('items')) {
            Session::push('items', [
                'item_id' => Input::get('item_id'),
                'item_quantity' => Input::get('item_quantity')
            ]);
            $array = Session::get('items');

            foreach($array as $key => $value) {
                foreach($value as $item_id => $item_quantity) {
                    $total = array();

                    $id = $value['item_id'];

                    $quantity = $value['item_quantity'];

                    if (!isset($total[$id])) {
                        $total[$id] = 0;
                    }

                    $total[$id] += $quantity;
                    echo $total[$id];

                }
            } else {
                Session::put('items', [
                    0 => [
                        'item_id' => Input::get('item_id'),
                        'item_quantity' => Input::get('item_quantity')
                    ]
                ]);
            }

            $data = Session::all();

            //return $data;

            $item = Item::lists('item_name', 'id');
            return View::make('test')->with('data', $data)->with('items', $item);
     }

2 Answers 2

2

You're on the right track. See comments in the code.

public function Save() {
  if (Input::has('addItem')) {
    if (Session::has('items')) {
      Session::push('items', [
          'item_id' => Input::get('item_id'),
          'item_quantity' => Input::get('item_quantity')
      ]);
      $array = Session::get('items');
      $total = array(); //move outside foreach loop because we don't want to reset it

      foreach ($array as $key => $value) {

          $id = $value['item_id'];
          $quantity = $value['item_quantity'];

          if (!isset($total[$id])) {
            $total[$id] = 0;
          }

          $total[$id] += $quantity;
          echo $total[$id];
      }

      //now convert our associative array from  array(actual_item_id => actual_item_quantity,....)
      //into array(array('item_id' => actual_item_id, 'item_quantity' => actual_item_quantity), ....)
      $items = array();

      foreach($total as $item_id => $item_quantity) {
        $items[] = array(
            'item_id' => $item_id,
            'item_quantity' => $item_quantity
        );
      }

      Session::put('items', $items);
    } else {
      Session::put('items', [
          0 => [
              'item_id' => Input::get('item_id'),
              'item_quantity' => Input::get('item_quantity')
          ]
      ]);
    }

    $data = Session::all();

    //return $data;

    $item = Item::lists('item_name', 'id');
    return View::make('test')->with('data', $data)->with('items', $item);
  }
}
Sign up to request clarification or add additional context in comments.

3 Comments

I tried out your code, works fine it adds all item_quantity with the same item_id but the item_quantity ends being twice the expected value.
@lozadaOmr can you try again? i removed one of the foreaches
Try to use class instance instead of facade. Like as Session::has('items') to $request->session()->has('items') Session::get('items') to $request->session()->get('items')
1

You could choose to create a new array, and from that, sum the values from the old. You could do something like this. Consider this example:

// dummy data
$raw = '{"items": [{ "item_id": "1", "item_quantity": "151"}, { "item_id": "2", "item_quantity": "54"}, { "item_id": "2", "item_quantity": "23"}, { "item_id": "3", "item_quantity": "3"}, { "item_id": "3", "item_quantity": "3"}]}';
$values = json_decode($raw); // for sample data's sake
$values = reset($values); // get first level 'items'

$new_values = array();
foreach($values as $key => $value) {
    if(!isset($new_values[$value->item_id])) $new_values[$value->item_id] = new stdClass(); // initialize new object
    if(!isset($new_values[$value->item_id]->item_quantity)) $new_values[$value->item_id]->item_quantity = 0; // initialize default value
    $new_values[$value->item_id]->item_id = $value->item_id; // append new item id
    $new_values[$value->item_id]->item_quantity += $value->item_quantity; // sum values
}

echo '<pre>';
print_r($new_values);
echo '</pre>';

Sample Output:

Array
(
    [1] => stdClass Object
        (
            [item_quantity] => 151
            [item_id] => 1
        )

    [2] => stdClass Object
        (
            [item_quantity] => 77
            [item_id] => 2
        )

    [3] => stdClass Object
        (
            [item_quantity] => 6
            [item_id] => 3
        )

)

Sample Fiddle

4 Comments

But that would require me to create and insert into the values array manually. But since the number of item_id's are dynamic I can't be sure how big it can get.
@lozadaOmr what are you referring to? the sample values? thats just a reference, the $values may represent the $array = Session::get('items');
I set the $values = Session::get('items'); it returned the error Trying to get property of non-object. On the line if(!isset($new_values[$value->item_id])) $new_values[$value->item_id] = new stdClass();
@lozadaOmr sorry i forgot you have items index, add $values = reset($values); after $values = Session::get('items');, check the edit

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.