Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Use Laravel Collection to get duplicate values

I don´t want to remove the duplicate values, I want to get the articles_id duplicates and sum their quantity values, for example, this is my collection:

Collection {#306 ▼
  #items: array:3 [▼
    0 => CartLine {#294 ▼
      +quantity: 2
      +article_id: 1728
      +article_name: "TAZA CERAMICA"
    }
    1 => CartLine {#296 ▼
      +parent_line_id: null
      +quantity: 1
      +article_id: 1728
      +article_name: "TAZA CERAMICA"
    }
    2 => CartLine {#298 ▼
      +quantity: 1
      +article_id: 1378
      +article_name: "JARRA CERVEZA ALEMANA"

    }
  ]
}

And I want get this result:

Collection {#306 ▼
  #items: array:3 [▼
    0 => CartLine {#294 ▼
      +quantity: 3 //sum total quantity of the duplicates elements with same article_id
      +article_id: 1728
      +article_name: "TAZA CERAMICA"
    }
    1 => CartLine {#296 ▼
      +parent_line_id: null
      +quantity: 3
      +article_id: 1728
      +article_name: "TAZA CERAMICA"
    }
    2 => CartLine {#298 ▼
      +quantity: 1
      +article_id: 1378
      +article_name: "JARRA CERVEZA ALEMANA"

    }
  ]
}

I want sum the quantities of the duplicate elements and set the quantity property with the sum in these elements.

like image 347
RichardMiracles Avatar asked Nov 30 '16 12:11

RichardMiracles


People also ask

How remove duplicates from laravel?

Example: $duplicateRecords = DB::select('name') ->selectRaw('count(`name`) as `occurences`') ->from('users') ->groupBy('name') ->having('occurences', '>', 1) ->get(); Then you need to loop through your collection and delete the items.

How do I remove duplicates from array in laravel?

We can get the unique elements by using array_unique() function. This function will remove the duplicate values from the array.

How do I count collections in laravel?

$coll = User::all(); echo $coll->count();


3 Answers

I know this answer was already accepted, but I just found this StackOverflow post when I was searching for the same thing. What I ended up doing was the following.

$users = Users::all();
$usersUnique = $users->unique('id');
$usersDupes = $users->diff($usersUnique);

dd($users, $usersUnique, $usersDupes);

I only needed mine for a one time purpose so I am not sure how performant this would be if you need to use it on production page.

like image 123
Matt Pramschufer Avatar answered Oct 12 '22 13:10

Matt Pramschufer


You could try something like:

$collection->groupBy('article_id')->flatMap(function ($items) {

    $quantity = $items->sum('quantity');

    return $items->map(function ($item) use ($quantity) {

        $item->quantity = $quantity;

        return $item;

    });

});

Obviously, change $collection to be whatever you've called the variable that holds your collection.

Hope this helps!

like image 42
Rwd Avatar answered Oct 12 '22 15:10

Rwd


Another one solution to obtain grouped duplicates:

    $collection = collect([
        [
            'name' => 'aa',
            'value' => 22
        ],
        [
            'name' => 'bb',
            'value' => 22
        ],
        [
            'name' => 'cc',
            'value' => 11
        ],
        [
            'name' => 'bb',
            'value' => 33
        ],
        [
            'name' => 'bb',
            'value' => 33
        ],
        [
            'name' => 'bb',
            'value' => 33
        ],
    ]);

    $groupedByValue = $collection->groupBy('value');

    $dupes = $groupedByValue->filter(function (Collection $groups) {
        return $groups->count() > 1;
    });

Output:

array:2 [▼
  22 => array:2 [▼
    0 => array:2 [▼
      "name" => "aa"
      "value" => 22
    ]
    1 => array:2 [▼
      "name" => "bb"
      "value" => 22
    ]
  ]
  33 => array:3 [▼
    0 => array:2 [▼
      "name" => "bb"
      "value" => 33
    ]
    1 => array:2 [▼
      "name" => "bb"
      "value" => 33
    ]
    2 => array:2 [▼
      "name" => "bb"
      "value" => 33
    ]
  ]
]
like image 28
Alexandr Mityuk Avatar answered Oct 12 '22 13:10

Alexandr Mityuk