-3

trying to attempt learn more about the new javascript syntax and came across this.

a.find(c=>!(a[-c]^=1))

I would very much appreciate it if someone could expand this out and explain the syntax for me.

For more clarity.

the array is a set of integers. The goal is to find the first duplicate in the set.

ie. if a = [1,2,4,5,4,1]

the function should return 4

a.find(c=>!(a[-c]^=1))

the above is the part of the function which finds first duplicate.

  1. specifically what i don't understand is how -c which is negative of the value in the set is helping not return undefined all the time since there is never a negative index in the array.
  2. a[-c]^=1 is some for of comparison that i'm not familiar with so an example of it's concept or a link to docs would be much appreciated.
  3. why is it evaluated with 1 Thank You.
Pierre Smith
  • 195
  • 2
  • 16
  • Depends on what `a` contains. What specifically don’t you understand? Have you checked the [documentation](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators)? Also see [What does this symbol mean in JavaScript?](https://stackoverflow.com/q/9549780/4642212). – Sebastian Simon Dec 27 '18 at 19:43
  • what are you trying to achieve? – Hith Dec 27 '18 at 19:48
  • 1
    `!` is the [Boolean not operator](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Logical_Operators#Logical_NOT_(!)), `a[...]` accesses a property on `a`, where the property name is result of evalating `-c`. `-` is the [unary negation operator](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Arithmetic_Operators#Unary_negation_(-)). `x ^= y` is the same as `x = x ^ y`. `^` is the [bitwise XOR operator](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Bitwise_Operators#(Bitwise_XOR)). – Felix Kling Dec 27 '18 at 19:49
  • I can guess that a is definitely array of negative numbers as then only it can give positive indices. – Sumer Dec 27 '18 at 19:58
  • ok sorry i didn't think the array contents matter i'll add more detail. – Pierre Smith Dec 27 '18 at 20:00

2 Answers2

1
a.find()

a is an Array and Array.prototype.find is looking for the first element that returns true or if no element has been found undefined.

Let's take a look into the arrow function.

c=>!(a[-c]^=1)

c represents an element in a and a[-c] references the entry with the index of negative c, further called b. !(b^=1) assigns b the result of the bitwise XOR assignment b^=1 or transformed b=b^1. The new value of b gets returned and every negated integer besides 0 returns false.

chr
  • 393
  • 3
  • 7
  • 1
    The last part is not quite right: `b^=1` is equal to `b = b ^ 1` which yields the XOR of `b` and `1`([XOR assignment operator](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Assignment_Operators#Bitwise_XOR_assignment_2)). It's not a comparison to `1`. Also `!` converts to boolean, i.e. `false` for negative numbers and `true` for positive (including zero). – FK82 Dec 27 '18 at 20:09
  • Thanks this is what I was looking for. The only questions i have left is why isn't the negative `c` not returning `undefined` all the time if the array doesn't have negative indexes. – Pierre Smith Dec 27 '18 at 20:10
  • @FK82 I actually don't understand the difference. Could you provide me with more details? – chr Dec 27 '18 at 20:14
  • @chr `b^=1` is an **assigment** operation, it assigns `b` the value of `b^1`. What you said would have to be written `b^1 === 1`. `!` isn't returning the negated value of `b^=1` since this is a number. For numbers `!` is boolean conversion. My first comment was wrong about the return value though: it's `true` for `0` and `false` for everything else. – FK82 Dec 27 '18 at 20:29
  • 1
    @PierreSmith You can actually use negative integers for indexing as well. They are being silently converted to strings: for example, let `const o = {'-1': 'a'};` then you can retrieve the value with the index `-1` and `o[-1] === 'a'` will return `true`. – FK82 Dec 27 '18 at 20:32
  • 1
    @FK82 thank you for your comment, I have edited my answer. – chr Dec 27 '18 at 20:40
  • @FK82 you are right, I was mistaken and deleted my comment. Assignments are returning the assigned value :). – chr Dec 27 '18 at 20:43
0

To understand, whats happen, you need to understand that an array is a special form of an object with some special feature.

In this case the array is (mis)used as storage for a temporary result of a flag, which is changed like a flip-flop with a bitwise XOR.

To see, what is in the array, you need to convert the array to an object. The content is the final value after returning from find.

The reason for taking negative indices is to keep the original values at the given indices.

var a = [1, 2, 4, 5, 4, 1]

console.log(a.find(c => !(a[-c] ^= 1)))

console.log(Object.assign({}, a));
Nina Scholz
  • 323,592
  • 20
  • 270
  • 324