2

I have 2 collections of models.

For example

$full = collect([
    [
        'name' => 'name1',  //id was omitted intentionally
    ],
    [
        'name' => 'name2', //id was omitted intentionally
    ],
    [
        'name' => 'name3', //id was omitted intentionally
    ],
]);

$diff = collect([
    [
        'id'   => 6,
        'name' => 'name1',
    ],
]);

and I want to receive such a result after something like this

$full->diff($full);

$result = [
    [
        'name' => 'name2',
    ],
    [
        'name' => 'name3',
    ],
];

How to achieve that without filter() or reject() with contains() in a neater way?

D.R.
  • 2,540
  • 3
  • 24
  • 49
  • 1
    I'm confused, you want a collection to take itself on a ->diff() method call and return part of itself back? what logic do you want it to use to decide what to return? – wheelmaker Sep 15 '18 at 20:57
  • Why would a diff return `name1`? Wouldn't you want `name2` and `name3`? – ourmandave Sep 15 '18 at 21:43
  • @mattQuest Probably I do not understand something in the 'diff' method, but I've written what I want to receive. Just subtract $diff from $full. How to achieve that? What function should I use? – D.R. Sep 15 '18 at 21:53
  • I think I got it... did you intend to put the $diff var in $full->diff($diff) instead of $full->diff($full). Also, did you intend to put 'name3' in the $diff collection? – wheelmaker Sep 15 '18 at 21:56
  • @mattQuest the output was intentional. – D.R. Sep 15 '18 at 22:12
  • @mattQuest OMG, soory. I saw a mistake. Updated. – D.R. Sep 15 '18 at 22:13
  • I've tried both ways to call `diff()`. None worked out for me)) – D.R. Sep 15 '18 at 22:15
  • I'm using `reject()` now, but is there any shorted way to do that? – D.R. Sep 15 '18 at 22:19

3 Answers3

2

It's hard to say why you don't want to use filter or reject with contains but there is another solution:

$result = $full->pluck('name')->diff($diff->pluck('name'))->map(function($name) {
        return [
            'name' => $name
        ];
    });

dd($result->toArray());

As result you will get:

array:2 [▼
  1 => array:1 [▼
    "name" => "name2"
  ]
  2 => array:1 [▼
    "name" => "name3"
  ]
]
Marcin Nabiałek
  • 109,655
  • 42
  • 258
  • 291
1

The diff method should work as needed with a new collection containing just the name property:

$comparableDiff = $diff->pluck('name');
$result = $full->diff($comparableDiff);
wheelmaker
  • 2,975
  • 2
  • 21
  • 32
0

I haven't found a neater approach than

$profiles->reject(function ($profile) use ($existingProfiles) {
    return $existingProfiles->pluck('name')->contains($profile->name);
})->values()

But thanks to everyone. I've upvoted your questions ;)

D.R.
  • 2,540
  • 3
  • 24
  • 49
  • But this is not what you asked :) You wanted solution without using `reject` and `contains` :) – Marcin Nabiałek Sep 16 '18 at 07:02
  • I should have written "that is neater"))) Sorry for not specifying that. Just, you know, we, devs, always aiming for perfection) – D.R. Sep 16 '18 at 13:55