Get a resulting array after removing similiar values from 2 different array - php

There are 2 set of code and each gives 2 different array
First set is this
$this->db->select('id');
$query = $this->db->get('user');
echo "<pre>";
print_r( $query->result());
echo "</pre>";
And gives the following result
Array
(
[0] => stdClass Object
(
[id] => 1
)
[1] => stdClass Object
(
[id] => 2
)
)
Second one is this
$this->db->select('user_id');
$query_two = $this->db->get('request_user');
echo "<pre>";
print_r( $query_two->result());
echo "</pre>";
And gives the following result
Array
(
[0] => stdClass Object
(
[user_id] => 1
)
)
I wish to get final array that should not have the duplicate values, eg in the above 2 array 1 is common in both the array so it should not be there and in resulting array i should get only value 2

You could take the following approach. Make a list of ids from your second array. And then use that list to filter the first. If an id is not in that list: keep it.
<?php
$one = [
(object) ['id' => 1],
(object) ['id' => 2],
];
$two = [
(object) ['id' => 1],
];
$ids_in_two = [];
foreach($two as $val) {
$ids_in_two[] = $val->id;
}
$filtered = array_filter($one, function($val) use ($ids_in_two) {
return !in_array($val->id, $ids_in_two);
});
var_dump($filtered);
Output:
array(1) {
[0]=>
object(stdClass)#1 (1) {
["id"]=>
int(2)
}
}

Related

Remove subsets from each row where the same subset is found in another row

I need to remove objects from a 3d array where the same two-property object is found in any other row.
I previously asked this similar question, but my new requirements are slightly different because I was keeping one of the encountered duplicates. Now I would like for both/all encountered duplicates to be removed.
[
[
["name" => "John", "surname" => "Smith"],
["name" => "Kate", "surname" => "Winston"]
],
[
["name" => "Kate", "surname" => "Winston"],
["name" => "Jack", "surname" => "Irving"]
],
]
Desired filtered result with same original structure:
[
[
["name" => "John", "surname" => "Smith"],
],
[
["name" => "Jack", "surname" => "Irving"]
],
]
Seems like others answers don't see their own final results and don't read desired output.
Here a little bit hard solution but it works well.
Note: the input data array must have 2 object indexes and 2 arrays of objects for comparing, otherwise, it should be fixed.
$ar = Array (
0 => [(object)["name"=>"John", "surname"=>"Smith"], (object)["name"=>"Kate", "surname"=>"Winston"]],
1 => [(object)["name"=>"Kate", "surname"=>"Winston"], (object)["name"=>"Jack", "surname"=>"Irving"]]
);
$arr = [];
$k = 0; // do `if statement` only once
foreach($ar as $num=>&$subar){
foreach($subar as $num2=>$pers){
$subar[$num2] = (array)$pers; // object to array
if (!$k) {
$keys = array_keys($subar[$num2]); // collect "name" and "surname" in an array
$k++;
}
foreach($subar[$num2] as $a=>$b){
$seq = array_search($a,$keys); // index of the current key
if (!$seq) { // 0 -> "name", 1 -> "surname"
$arr[$num][$b] = '';
} else {
$arr[$num][$subar[$num2][current($keys)]] = $b;
}
}
}
}
$diff[] = array_diff($arr[0],$arr[1]); // clear duplicates from 1-st set
$diff[] = array_diff($arr[1],$arr[0]); // clear duplicates from 2-nd set
Gives result:
Array
(
[0] => Array
(
[John] => Smith
)
[1] => Array
(
[Jack] => Irving
)
)
And after you can re-create the output array:
// creating a new array
$res = [];
foreach($diff as $num=>$ns){
foreach($ns as $name=>$surname){
foreach($keys as $ind=>$key){
if ($ind % 2 == 0){
$tmp[$key] = $name; // put name
} else {
$tmp[$key] = $surname; // put surname
}
}
$res[$num] = (object)$tmp; // array to object
}
}
Output will be:
Array
(
[0] => stdClass Object
(
[name] => John
[surname] => Smith
)
[1] => stdClass Object
(
[name] => Jack
[surname] => Irving
)
)
Demo
In case of string values in the input arrays, i.e.:
$ar = [
'[{"name":"John", "surname":"Smith"}, {"name":"Kate", "surname":"Winston"}]',
'[{"name":"Kate", "surname":"Winston"}, {"name":"Jack", "surname":"Irving"}]'
];
You need a little fix:
...
foreach($ar as $num=>&$subar){
$ar[$num] = json_decode($subar);
foreach($subar as $num2=>$pers){
...
The same output you will get.
Demo
It's easier if you don't trim away the brackets [], as you stated that you did in the comments. That way, they are proper JSON strings, which we can use in PHP.
Map (or loop) over your array, and build up a $result array, where you append all the arrays from your decoded JSON. Once you have your final $result, you have an array that looks somewhat like
Array (
[0] => Array
(
[name] => John
[surname] => Smith
)
[1] => Array
(
[name] => Kate
[surname] => Winston
)
[2] => Array
(
[name] => Kate
[surname] => Winston
)
[3] => Array
(
[name] => Jack
[surname] => Irving
)
)
We have all the values in an actual array now, but there are duplicates -- which can be removed using array_unique() with the SORT_REGULAR flag.
$array = [
'[{"name":"John", "surname":"Smith"}, {"name":"Kate", "surname":"Winston"}]',
'[{"name":"Kate", "surname":"Winston"}, {"name":"Jack", "surname":"Irving"}]'
];
$result = [];
array_map(function($v) use (&$result) {
$result = array_merge($result, json_decode($v, true));
}, $array);
print_r(array_unique($result, SORT_REGULAR));
Final output:
Array
(
[0] => Array
(
[name] => John
[surname] => Smith
)
[1] => Array
(
[name] => Kate
[surname] => Winston
)
[3] => Array
(
[name] => Jack
[surname] => Irving
)
)
Live demo at https://3v4l.org/q6pZc
$array = [
'[{"name":"John", "surname":"Smith"}, {"name":"Kate", "surname":"Winston"}]',
'[{"name":"Kate", "surname":"Winston"}, {"name":"Jack", "surname":"Irving"}]'
];
$resultArray = [];
foreach ($array as $item) {
$bufferArray = array_merge($resultArray, json_decode($item));
foreach ($bufferArray as $elements) {
$key = $elements->name . $elements->surname;
if (array_key_exists($key, $resultArray)) {
unset($resultArray[$key]);
} else {
$resultArray[$key] = $elements;
}
}
}
print_r($resultArray);
Output
Array
(
[KateWinston] => stdClass Object
(
[name] => Kate
[surname] => Winston
)
[JackIrving] => stdClass Object
(
[name] => Jack
[surname] => Irving
)
)
can rewrite this into more serious code )
To remove objects from each row where a given object exists any where in any other row, you can make iterates calls of array_udiff(). Inside the function, the first parameter should be the currently iterated row and the next/subsequent parameter(s) should all of the other rows in the entire array. The last parameter is the callback which compares whole objects to whole objects via PHP's performance-optimized algorithm.
My snippet below will not only handle your 2-row array, it will also handle arrays with 3 or more rows.
Code: (Demo)
$result = [];
foreach ($array as $i => $objs) {
$cache = $array[$i];
unset($array[$i]);
$params = [
$objs,
...$array,
fn($a, $b) => $a <=> $b
];
$result[] = array_udiff(...$params);
$array[$i] = $cache;
}
var_export($result);
To be clear, this snippet will work the same if the array of arrays of objects is an array of arrays of arrays.

If condition to check value of multiple column array php

I am trying to get value of is_activated column key. But can not get the exact value. Have tried array_search()
Review the array
Need to check value of all is_activated key whether it's value is 1 or not.
Array
(
[0] => Array
(
[first_name] => Array
(
[0] => john
)
[is_activated] => Array
(
[0] => 0
)
)
[1] => Array
(
[first_name] => Array
(
[0] => mark
)
[is_activated] => Array
(
[0] => 1
)
)
[2] => Array
(
[first_name] => Array
(
[0] => pretik
)
[is_activated] => Array
(
[0] => 0
)
)
)
I have tried this below solution but can can not get result.
$is_user_activated = array_search(1,array_column($activity,'is_activated'));
if($is_user_activated == 1) { echo 'yes'; }
else { echo 'no'; }
I think you want to be doing this in a loop rather than using array_search. Use a foreach() to get your desired result:
foreach($yourArray as $item) {
if($item['is_activated'][0] == 1) {
echo 'yes';
} else {
echo 'no';
}
}
You can use the array_filter() for such tasks, it allows to use a callback filter function:
<?php
$data = [
[
'first_name' => ['john'] ,
'is_activated' => [0]
],
[
'first_name' => ['mark'],
'is_activated' => [1]
],
[
'first_name' => ['pretik'],
'is_activated' => [0]
]
];
$matches = array_filter($data, function($entry) {
return in_array(1, $entry['is_activated']);
});
var_dump($matches);
The output of that is:
array(1) {
[1]=>
array(2) {
["first_name"]=>
array(1) {
[0]=>
string(4) "mark"
}
["is_activated"]=>
array(1) {
[0]=>
int(1)
}
}
}
Reason why that is a bit awkward is that your initial data has a very strange structure: the values of the elements are arrays themselves holding the actual values instead of scalar values themselves. That makes searching more complex than in "normal" situations. So take a good look if maybe you can fix that strange structure instead to be able to use an easier search approach.
You can get the activated users via array_filter:
$activated = array_filter($users, function($record) {
return reset($record['is_activated']) == 1;
});
This will only keep users who are activated, you can then simply count the array to see if you have any activated users:
echo count($activated) ? 'yes' : 'no';
Example here: http://ideone.com/mMuJcO

PHP- in_array() expects parameter 2 to be array

I have two arrays- one single and other multi-dimensional.
$abc='["first","second","third","fourth"]';
$def='[{"post_id":"1","postid":"42","tags":["eminem","baby","jordan"]},{"post_id":"3","postid":"38","tags"
:["abc","def","jordan"]},{"post_id":"4","postid":"40","tags":["eminem","baby","first","second","fourth"
]}]';
$ghi=json_decode($def,true);
$jkl=json_decode($abc,true);
echo '<pre>';
print_r($jkl);
echo '</pre>';
echo '<pre>';
print_r($ghi);
echo '</pre>';
And this is what it looks like:
Array
(
[0] => first
[1] => second
[2] => third
[3] => fourth
)
Array
(
[0] => Array
(
[post_id] => 1
[postid] => 42
[tags] => Array
(
[0] => eminem
[1] => baby
[2] => jordan
)
)
[1] => Array
(
[post_id] => 3
[postid] => 38
[tags] => Array
(
[0] => abc
[1] => def
[2] => jordan
)
)
[2] => Array
(
[post_id] => 4
[postid] => 40
[tags] => Array
(
[0] => eminem
[1] => baby
[2] => first
[3] => second
[4] => fourth
)
)
)
What I am trying to do is search for the elements of single-dimensional array inside the sub-array tags present in the multi-dimensional array.
This is my code:
$users = array_unique($jkl);
$array = [];
$i=0;
foreach($users as $user)
{
if (in_array($user, $ghi[$i]['tags']))
{
$newdata = array (
'postId' => $ghi[$i]['postid'],
'tag' => $user
);
array_push($array, $newdata);
}
$i++;
}
But I get the error mentioned as the question title.
What could be the possible reason? Thanks!
You have to iterate through multi-dimensional array and do what you want:-
<?php
$abc='["first","second","third","fourth"]';
$def='[{"post_id":"1","postid":"42","tags":["eminem","baby","jordan"]},{"post_id":"3","postid":"38","tags"
:["abc","def","jordan"]},{"post_id":"4","postid":"40","tags":["eminem","baby","first","second","fourth"
]}]';
$ghi=json_decode($def,true);
$jkl=json_decode($abc,true);
$users = array_unique($jkl);
$array = []; // empty array
foreach($ghi as $gh) // iterate through multi-dimensional array not single one
{
for($i=0;$i<count($users);$i++){ // a for loop to iterate through single-dimensional completly
if (in_array($users[$i],$gh['tags'])) // if single dimensional array value exist in multi-dimensional tags array
{
$newdata = array (
'postId' => $gh['postid'],
'tag' => $users[$i]
);
array_push($array, $newdata); // push the data
}
}
}
echo "<pre/>";print_r($array); // print newly created array
?>
Output:-https://eval.in/602523
Note:- Try to put variable name in such a way that they don't produce ambiguity.Thanks
Your both array has different numbers of elements. first array has four elements while second array has three elements. that's why you are getting problem.
You should check variable is set and must be an array. Use !empty() and is_array()
foreach($users as $k=>$user){
if(!empty($ghi[$k]['tags']) && is_array($ghi[$k]['tags'])) { // check this condition here
if (in_array($user, $ghi[$k]['tags'])){
$newdata = array (
'postId' => $ghi[$k]['postid'],
'tag' => $user
);
array_push($array, $newdata);
}
}
}
Note:- I have used array key as $k instead of $i
This is because length of your 2 arrays are different, use isset() to remove error:
as 3rd index of your $ghi array does not exist, and its trying to fetch $ghi[3]['tags'] - that's why error is occurring
Try:
foreach($users as $user)
{
if(isset($ghi[$i]['tags'])) { // just add this condition here
if (in_array($user, $ghi[$i]['tags']))
{
$newdata = array (
'postId' => $ghi[$i]['postid'],
'tag' => $user
);
array_push($array, $newdata);
}
}
$i++;
}
It depends on what you are searching for.
If you want to examine ALL of the $users against ALL of the $ghi array then you need to loop over both each time.
foreach($users as $user)
{
for ($i = 0; $i < count($ghi); $i++) {
if (in_array($user, $ghi[$i]['tags']))
{
$newdata = array (
'postId' => $ghi[$i]['postid'],
'tag' => $user
);
array_push($array, $newdata);
}
}
}
This will result in the $newdata consisting of the following
array(2) { ["postId"]=> string(2) "40" ["tag"]=> string(6) "fourth" }
But if you only want to examine the each array against the other once. Then you need to check to make sure you're not going out of bounds.
$ghi only has 3 elements in it.
there are 4 elements in $users.
So you can either loop through the smaller array in your foreach - switch $users -> $ghi
or check inside the foreach loop that $ghi has a valid element at whatever $i is.
D.

2 arrays match data into 1 array with PHP

I have 2 array's, first array have for example ItemID of my item, second array have description about my item. I want to match data into 1 array.
It looks like:
[rgInventory] => Array
(
[1234567890] => Array
(
[id] => 1234567890
[classid] => 123456789
[instanceid] => 987654321
[amount] => 1
[pos] => 1
)
)
[rgDescriptions] => Array
(
[192837465_918273645] => Array
(
[appid] => 730
[name] => Something
)
)
Items in arrays don't have the same value like ID, but they are in the same order so:
Description for the first item in rgInventory is in the first array inside rgDescriptions.
What should I do to match for example id from rgInventory with name from rgDescriptions in the same array for example $backpack = array();?
Regards for you.
Try this:
<?php
$array1 = array('rgInventory' =>
array(
'1234567890' => array(
'id' => 1234567890,
'classid' => 123456789,
'instanceid' => 987654321,
'amount' => 1,
'pos' => 1
)
)
);
$array2 = array(
'rgDescriptions' => array(
'192837465_918273645' => array(
'appid' => 730, 'name' => 'Something')
)
);
Create new function to combine the two arrays into one array:
function array_sum_recursive($data1, $data2) {
if (!is_array($data1) && !is_array($data2)) {
return $data1 + $data2;
}
// deepest array gets precedence
if (!is_array($data2)) {
return $data1;
}
if (!is_array($data1)) {
return $data2;
}
//merge and remove duplicates
$keys = array_unique(array_merge(array_keys($data1), array_keys($data2)));
foreach ($keys as $key) {
if (isset($data1[$key]) && isset($data2[$key])) {
$result[$key] = array_sum_recursive($data1[$key], $data2[$key]);
} else if (isset($data1[$key])) {
$result[$key] = $data1[$key];
} else {
$result[$key] = $data2[$key];
}
}
if(empty($result)){
echo "no result";
die();
}else{
return $result;
}
}
Put the two array in one array $newarray:
$newonearray = array_sum_recursive($array1, $array2);
echo '<pre>';
print_r($newonearray);
?>
And you will get this:
Array
(
[rgInventory] => Array
(
[1234567890] => Array
(
[id] => 1234567890
[classid] => 123456789
[instanceid] => 987654321
[amount] => 1
[pos] => 1
)
)
[rgDescriptions] => Array
(
[192837465_918273645] => Array
(
[appid] => 730
[name] => Something
)
)
)
Hope this may help.
You can use function each to get each element of both arrays, then merge its with array_merge and save this new item to backup array.
Try something like this
<?php
$rgInventory = ['firstInv' => ['invId' => 1], 'secondInv' => ['invId' => 2]];
$rgDescriptions = ['firstDesc' => ['descId' => 1], 'secondDesc' => ['descId' => 2]];
if (count($rgInventory) && count($rgInventory) == count($rgDescriptions)) {
$backpack = [];
while($inventory = each($rgInventory)) {
$description = each($rgDescriptions);
$item = array_merge($inventory['value'], $description['value']);
$backpack[] = $item;
}
var_dump($backpack);
}
Output will be:
array(2) {
[0]=>
array(2) {
["invId"]=>
int(1)
["descId"]=>
int(1)
}
[1]=>
array(2) {
["invId"]=>
int(2)
["descId"]=>
int(2)
}
}

Combine two arrays into a single array based on a common column value

I am trying to combine two arrays while respecting their shared value.
$array1 = array(
array("id" => "1","name"=>"John"),
array("id" => "2","name"=>"Peter"),
array("id" => "3","name"=>"Tom"),
array("id" => "12","name"=>"Astro")
);
$array2 = array(
array("id" => "1","second_name"=>"Lim"),
array("id" => "2","second_name"=>"Parker"),
array("id" => "3","second_name"=>"PHP")
);
My expected output:
$result = array(
array("id" => "1","name"=>"John","second_name"=>"Lim"),
array("id" => "2","name"=>"Peter","second_name"=>"Parker"),
array("id" => "3","name"=>"Tom","second_name"=>"PHP"),
array("id" => "12","name"=>"Astro")
);
I have made a try by
$arraycomb = array_unique(array_merge($array1,$array2), SORT_REGULAR);
My output is:
Array
(
[0] => Array
(
[id] => 1
[name] => John
)
[1] => Array
(
[id] => 2
[name] => Peter
)
[2] => Array
(
[id] => 3
[name] => Tom
)
[3] => Array
(
[id] => 12
[name] => Astro
)
[4] => Array
(
[id] => 1
[second_name] => Lim
)
[5] => Array
(
[id] => 2
[second_name] => Parker
)
[6] => Array
(
[id] => 3
[second_name] => PHP
)
)
How can I combine the key value inside same array? or how can I bring the expected output?
Note: I am trying for value instead of key ref: PHP Array Merge two Arrays on same key
Alternatively, you could use a foreach in this case then merge them if they share the same id key
With using reference &
foreach($array1 as &$value1) {
foreach ($array2 as $value2) {
if($value1['id'] == $value2['id']) {
$value1 = array_merge($value1, $value2);
}
}
}
echo '<pre>';
print_r($array1);
You can use array_map() for this. Try this -
function modifyArray($a, $b)
{
if (!empty($a) && !empty($b)) {
return array_merge($a, $b);
} else if (!empty($a) && empty($b)) {
return $a;
} else if (empty($a) && !empty($b)) {
return $b;
}
}
$new = array_map("modifyArray", $array1, $array2);
var_dump($new);
It will generate the new array will all the values in both arrays.if the first array's element is empty then the second array will be merged and vice-versa.
Assign temporary first level keys to your first array to aid in identifying rows. Then loop the second array and append the desired column value to the appropriate group. Re-index the array after looping with array_values().
Code: (Demo)
$result = array_column($array1, null, 'id');
foreach ($array2 as $row) {
$result[$row['id']]['second_name'] = $row['second_name'];
}
var_export(array_values($result));
This is a more direct approach than brute force scanning arrays with nested loops.
If all ids in the second array exist in the first array, then the following simpler line can be written inside the body of the foreach().
$result[$row['id']] += $row;

Categories