How to Remove Values from Two Arrays That Have the Same Key and Value

How to remove values from two arrays that have the same key and value?

array_unique( array_merge($arr_1, $arr_2) );

or you can do:

$arr_1_final = array_diff($arr_1, $arr_2);
$arr_2_final = array_diff($arr_2, $arr_1);

Json decode and filter a deep subarray of a 3d array using the values from a column in another 3d array

Here you go, I made it fancy for you.

$arr1 = [
99 => [
"number" => [1,3]
],
88 => [
"number" => [12,13,21]
]
];

$arr2 = [
["a"=>"01","b"=> '["01", "02", "03", "04"]'],
["a"=>"02","b"=> '["11", "12", "13"]'],
["a"=>"03","b"=> '["21", "22", "23"]']
];

$numbers = preg_replace('/^(\d)$/', '0\1', array_merge(...array_column($arr1, 'number')));

array_walk($arr2, function(&$item)use($numbers){
$item['b'] = array_diff(json_decode($item['b'], true),$numbers);
});

print_r($arr2);

Output

Array
(
[0] => Array
(
[a] => 01
[b] => Array
(
[1] => 02
[3] => 04
)

)

[1] => Array
(
[a] => 02
[b] => Array
(
[0] => 11
)

)

[2] => Array
(
[a] => 03
[b] => Array
(
[1] => 22
[2] => 23
)

)

)

Sandbox

How it works.

Whenever you find your self in a situation where you need to compare one multi-dimensional array to another remember array_column. This allows you to pull out one column from the nested arrays. What that does is simplify one of the arrays and makes things a bit easier.

So lets go thought the above code function by function (in the order they are called):

array_column($arr1, 'number');
//Output: [[1,3],[12,13,21]]

This is not quite what we need and we can simplify it a bit more using array_merge and variadic ( PHP >= 5.6) or variable length arguments. The ... which has this effect:

 array_merge([1,3],[12,13,21]); //each nested array is a new argument
//Output: [1,3,12,13,21]

Now we have something simple to work with, but there is still one issue. This is that the values in the other list are strings with leading 0s and in your expected output you retain these. So to fix that we can use preg_replace.

preg_replace('/^(\d)$/', '0\1',[1,3,12,13,21])
//Output: ['01','03','12','13','21']

//non regex methods
//array_map(function($v){return strlen($v)>1?$v:"0$v";},[1,3,12,13,21])
//array_map(function($v){return str_pad($v,2,'0',STR_PAD_LEFT);},[1,3,12,13,21])

The Regex ^(\d)$ simply matches elements with only 1 digit. Then we capture that and use it in the replacement 0\1. The \1 transfers that number we captured into that "replacement" string. This effectively adds a leading 0 on items with 1 digit, which is what we need. There is a few non-regex ways you could do this but none of them are as "pretty", see the above non-regex example.

I will assume json_decode needs no introduction.

Then we simply loop over them (array_walk in this case), and use array_diff to compare the 2 arrays. This return only the items in array1 that are not in array2. So for this

 //loop1
array_diff(["01", "02", "03", "04"],['01','03','12','13','21']);
//Output: ["02", "04"]

//loop2
array_diff(["11", "12", "13"],['01','03','12','13','21']);
//Output: ["11"]

//loop3
array_diff(["21", "22", "23"],['01','03','12','13','21']);
//Output: ["22", "23"]

Then because were updating by reference function(&$item) in our closure, we are all done.

Yea that was fun! Unfortunately I don't see a way to do this in 1 line, however what I have is essentially 2 lines so that's not so bad...

Hope that helps explain it.

Update

I lied, I figured out how to do it in 1 line (165 bytes):

  array_walk($arr2,function(&$i,$k,$n){$i['b']=array_diff(json_decode($i['b'],true),$n);},preg_filter('/^(\d)$/','0\1',array_merge(...array_column($arr1,'number'))));

To do this (I remembered) you can pass additional arguments into array_map so that is what I did. This avoids the assignment issues with the use statement. It's like any function you cannot set a default that is the result of another function call.

 //for example this doesn't work
function(&$item)use($numbers = preg_replace(...)){ ... }

But this does (additional argument is $n in this case):

 array_walk($arr2,function(&$i,$k,$n){....},preg_replace(...));

Sandbox

Summery

Essentially what I am doing, is taking one of the arrays and making it the same format as what we want to compare it to. That way, we simplify the problem, instead of just throwing a ton of code at it. It's always better to reduce complexity, granted this is "complex" if you don't know what these functions do on an intimate level. But I do know this so it's not so hard to read for me.

Cheers!

How to compare two different array and remove object from one Array based on Key?

Since you tagged lodash, you can consider using the _.differenceWith() method, which allows you to provide a comparator function to specify what property you should take the difference by. However, if you're not already using lodash, then a vanilla approach is preferable.

const arr1 = [{id: "one", name: "one", status: "Active"},  {id: "two", name: "two", status: "Active"}, {id: "three", name: "three", status: "Active"}];
const arr2 = [{pid: "one", order: 1}, {pid: "two", order: 2}];
const res = _.differenceWith(arr1, arr2, ({id}, {pid}) => id === pid);

console.log(res); // [{ "id": "three", "name": "three", "status": "Active" }]
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.15/lodash.min.js"></script>

How to remove objects with the same key and value pair in arrays

You can compare the two items using JSON.stringify(). We then add to a new array using reduce, if it is in the array we don't add it otherwise we do add it.

const array = [{a:1},{a:2},{c:3},{b:1},{a:1},{c:3},{c:4},{a:1}]
let unique = array.reduce((res, itm) => { // Test if the item is already in the new array let result = res.find(item => JSON.stringify(item) == JSON.stringify(itm)) // If not lets add it if(!result) return res.concat(itm) // If it is just return what we already have return res}, [])
console.log(unique)

Compare keys and values from two arrays and print all values including duplicates

You cannot create an array with twice the same key, in your case 'L'. What you can do is this:

$name = 'ALLISON';

function toNumber($name) {

$nameArr = str_split($name);

$convertArr = array(
'A'=>'1', 'J'=>'1', 'S'=>'1',
'B'=>'2', 'K'=>'2', 'T'=>'2',
'C'=>'3', 'L'=>'3', 'U'=>'3',
'D'=>'4', 'M'=>'4', 'V'=>'4',
'E'=>'5', 'N'=>'5', 'W'=>'5',
'F'=>'6', 'O'=>'6', 'X'=>'6',
'G'=>'7', 'P'=>'7', 'Y'=>'7',
'H'=>'8', 'Q'=>'8', 'Z'=>'8',
'I'=>'9', 'R'=>'9'
);

return array_reduce($nameArr, function ($carry, $item) use ($convertArr) {
return [ ...$carry, [$item => $convertArr[$item]] ];
}, []);

}

print_r(toNumber($name));

It will create an array of arrays:

Array
(
[0] => Array
(
[A] => 1
)

[1] => Array
(
[L] => 3
)

[2] => Array
(
[L] => 3
)

[3] => Array
(
[I] => 9
)

[4] => Array
(
[S] => 1
)

[5] => Array
(
[O] => 6
)

[6] => Array
(
[N] => 5
)

)

how to remove duplicate object from array by comparing two keys in same array?

The problem you're facing now is due to the line:

if (el.p_id== el.p_id && el.c_code== el.c_code)

Which will always hit, since el.p_id== el.p_id && el.c_code== el.c_code is always true because you're comparing the element to itself.

Instead use an Set to store and check which values you've already added. Use a JSON string as unique key. This can be achieved by JSON.stringify an array of the relevant property values.

Then return a falsy value to exclude the current item if the key is present in a set. If the key is not present, add the key to the set and return a truthy value to include the current item.

const campaigns = [  {id:"1", p_id:"mobile", c_code:"aaa"},  {id:"1", p_id:"mobile", c_code:"aaa"},  {id:"2", p_id:"electronics", c_code:"aaa"},  {id:"1", p_id:"mobile", c_code:"bbb"},  {id:"2", p_id:"electronics", c_code:"bbb"},  {id:"2", p_id:"electronics", c_code:"bbb"}];
const lookup = new Set();console.log( campaigns.filter(campaign => { // stringify an array of the properties you want to use for uniqueness const key = JSON.stringify([campaign.p_id, campaign.c_code]); return !lookup.has(key) && lookup.add(key); }));

How can i compare two arrays for a value and remove that value from only one of the arrays

This answer would be a great place to start for understanding how to remove an item from an array.

Arrays in javascript are a type of object. Objects are keys and values.
If you want to a function that will take this array

[2, 4, 7, 2, 9, 4, 0, 3, 6, 2]; 

and return this array

[2, 4, 7, 2, 4, 0, 3, 6, 2];

You are technically manipulating more than just the value 9 at key 4. You would be reassigning a new key to each value following the space the value 9 used to be in as well.

If you are trying to return an array that is filtered based on certain criteria, such as the number being 9, you could use the method .filter (docs)

A brief overview of .filter, the method has optional arguments and functionality that is beyond the scope of a brief overview, but to keep things short; the .filter method takes a callback function as an argument. The callback function will be applied to each item in the array, with the item being passed as an argument. If the function returns true, the item will be returned in the result. If the function returns false, the item will not be returned in the result.

i.e.

console.log(
[2, 4, 7, 2, 9, 4, 0, 3, 6, 2]
.filter(number => number !== 9)
.toString()
);
/*styling console display -- not relevant to answer*/
.as-console-wrapper { max-height: 100% !important; top: 0; }


Related Topics



Leave a reply



Submit