1

Let, I have two arrays with strings.

let a = ["ABC", "DEF"] let b = ["ABC", "DEF", "GHI"] 

I want to compare the above two arrays and make a new array called c which contains the following.

c = ["GHI"] 

So, I want to compare a and b arrays and push the non-identical elements into a new array.

How to do this in React Native?

5
  • Does b always contain every element of a? Commented May 14, 2019 at 5:39
  • May be not. Sometimes, B may be like b=["ABC"]. Then c should be like c=["DEF"] Commented May 14, 2019 at 5:44
  • @SennenRandika If the same array contains duplicate elements you want to remove it. If a=['ABC','ABC'] and b = ['DEF'] what will be result? Commented May 14, 2019 at 5:48
  • Possible duplicate of Simplest code for array intersection in javascript Commented May 14, 2019 at 5:53
  • @MaheerAli Then, c should be like, c = ['DEF']. Sorry for the mistake I've done in the previous comment. Commented May 14, 2019 at 6:15

3 Answers 3

3

You can do that in following steps:

  • First get those elements of a which are not in b
  • Then get those elements of b which are not in a
  • Then concat() both the arrays.

let a = ["ABC", "DEF"] let b = ["ABC", "DEF", "GHI"] const res = a.filter(x => !b.includes(x)).concat(b.filter(x=> !a.includes(x))) console.log(res)

How the code works

Consider the line

a.filter(x => !b.includes(x)) 

filter() is array method which takes a callback. If callback returns true then the element will be added to result array otherwise not.

So now in above code x is element of array b through which we are iterating. b.includes(x) will return true if x is present in array b otherwise false.

! operator converts true to false and vice verse

So if x will be inside b it will return true. So by ! it will be become false and false will be returned from callback. So the element x will not be included in result/filtered array.

The sentence for the line above line is that "It get only those items of array a which are not present in b"

The second line

b.filter(x=> !a.includes(x)) 

Gets those elements of b which are not in a.

Atlast concat() is used to join both array.

Sign up to request clarification or add additional context in comments.

3 Comments

Thank you so much for your answer. This solution perfectly works. Can you please explain me step-by-step how the line a.filter(x => !b.includes(x)).concat(b.filter(x=> !a.includes(x))) works?
@SennenRandika I have added a detailed explanation. Check it and if you don't understand something feel free to ask.
Perfect explanation!! Thank you so much for your answer and explanation. Used your answer and achieved what I wanted. Works perfectly.
2

You can also use Array.reduce and Array.filter like so:

const findUniques = (a,b) => [...a,...b].reduce((r,c,i,a) => { a.filter(x => x===c).length === 1 ? r.push(c) : null return r }, []) console.log(findUniques(["ABC", "DEF"], ["ABC", "DEF", "GHI"])) console.log(findUniques(["ABC", "DEF"], ["ABC"])) console.log(findUniques(["ABC", "DEF", "AAA"], ["AAA", "DEF", "GHI"]))

If you are using lodash this becomes really trivial with xor:

console.log(_.xor(["ABC", "DEF"], ["ABC", "DEF", "GHI"])) console.log(_.xor(["ABC", "DEF"], ["DEF"])) console.log(_.xor(["ABC", "DEF", "AAA"], ["AAA", "DEF", "GHI"]))
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.min.js"></script>

3 Comments

Thank you for your answer!! This works!! Can you please explain me step-by-step how the line a.filter(x => x===c).length === 1 ? r.push(c) : null works?
Since we are using Array.reduce (a) is the actual input array we are reducing. So we are filtering inside of the reduce the main array to see which elements would be found ONLY once. Hence the x===c. Then those elements we push to the accumulator r. For those filtered values which have more than one hit we do nothing. Hence null. Hope this helps.
its lifesaver lodash func thanx !
0

If you want to prevent going through the arrays O(n²) times, due to having to search each array for duplicate values, you could take advantage of the performance of JavaScript Objects.

const a = ["ABC", "DEF", "JKL"] const b = ["ABC", "DEF", "GHI"] const getUniqueValues = (a, b) => { const uniqueValuesObject = [...a, ...b].reduce((uniqueValuesObject, value) => { // if the value already exists, then it is not unique if (uniqueValuesObject[value]) { uniqueValuesObject[value] = false } else { uniqueValuesObject[value] = true } return uniqueValuesObject }, {}) return Object.entries(uniqueValuesObject).reduce((uniqueValues, [value, isUnique]) => { if (isUnique) { uniqueValues.push(value) } return uniqueValues }, []) } const c = getUniqueValues(a, b) console.log(c)

This can be shortened by using delete, however I am unsure if that will cause a performance hit compared to the solution above.

const a = ["ABC", "DEF", "JKL"] const b = ["ABC", "DEF", "GHI"] const getUniqueValues = (a, b) => { const uniqueValuesObject = [...a, ...b].reduce((uniqueValuesObject, value) => { // delete if the value already exists if (uniqueValuesObject[value]) { delete uniqueValuesObject[value] } else { uniqueValuesObject[value] = true } return uniqueValuesObject }, {}) return Object.keys(uniqueValuesObject) } const c = getUniqueValues(a, b) console.log(c)

3 Comments

Thank you for your answer!! What is the time complexity of the above solution?
@SennenRandika honestly, that depends on how Objects are implemented in whatever JavaScript engine you are using. For simplicity, if we assume that Objects are simply hash tables, then with the first solution it is possible to have an Object lookup of O(1), making the solution O(n) since all it does it traverse both arrays twice. Hash tables can have a worst time complexity of O(n) if many elements are hashed to the same key, which could give this O(n²) complexity, but it's unlikely. At the very least, it is much faster than searching the array using filter.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.