I'm trying to implement DLX in Javascript and I'm running into problems with updating self-referencing objects literals.
This function takes a binary matrix and returns a matrix where every '1' of the matrix is an object referencing it's closed '1' in all cardinal directions.
export const constructDataObjects = matrix => {
for (let i = 0; i < matrix.length; i++) {
for (let j = 0; j < matrix.length; j++) {
let u = j - 1;
let d = j + 1;
let l = i - 1;
let r = i + 1;
if (matrix[i][j] === 0) continue;
// Check edge cases.
if (u < 0) u = matrix.length - 1;
if (d >= matrix.length) d = 0;
if (l < 0) l = matrix.length - 1;
if (r >= matrix.length) r = 0;
// Increment and decrement directions, with bound checks.
// On hitting a bound, circle around and start from the other side.
while (matrix[i][u] === 0) u = u - 1 < 0 ? matrix.length - 1 : u - 1;
while (matrix[i][d] === 0) d = d + 1 >= matrix.length ? 0 : d + 1;
while (matrix[l][j] === 0) l = l - 1 < 0 ? matrix.length - 1 : l - 1;
while (matrix[r][j] === 0) r = r + 1 >= matrix.length ? 0 : r + 1;
matrix[i][j] = {
_u: undefined,
_d: undefined,
_l: undefined,
_r: undefined,
get u () { return this._u },
set u (v) { return this._u = v },
get d () { return this._d },
set d (v) { return this._d = v },
get l () { return this._l },
set l (v) { return this._l = v },
get r () { return this._r },
set r (v) { return this._r = v },
c : null,
debug: `i:${i}, j:${j}, u:${u}, d:${d}, l:${l}, r:${r}`
};
matrix[i][j].u = matrix[i][u]
matrix[i][j].d = matrix[i][d]
matrix[i][j].l = matrix[l][j]
matrix[i][j].r = matrix[r][j]
}
}
return matrix;
};
I asked a question before when I ran into problems with creating self-references in object literal declarations and was suggested to use getters. Now in DLX the objects in the data structure need to be able to change. How can I create editable self-referencing object literals?
I believe this problem can be reduced to
let a = arr => {
for(let i = 0; i < arr.length; i++) {
arr[i] = {
curr: arr[i],
first: arr[0],
last: arr[arr.length - 1],
}
}
return arr
}
console.log(a([1,2]))
For clarity let me denote *first
as a reference to the object in arr[0]
and *second
as a reference to the object in arr[1]
.
Now a([1,2])
produces
[ { curr: 1, first: 1, last: 2 },
{ curr: 2, first: *first, last: 2 } ]
What I want is
[ { curr: *first, first: *first, last: *second } },
{ curr: *second, first: *first, last: *second } ]
Add the getters
let a = arr => {
for(let i = 0; i < arr.length; i++) {
arr[i] = {
get curr () { return arr[i] },
get first () { return arr[0] },
get last () { return arr[arr.length - 1] }
}
}
return arr
}
console.log(a([1,2]))
Now a([1,2])
produces what I want
[ { curr: *first, first: *first, last: *second } },
{ curr: *second, first: *first, last: *second } ]
Lets add the ability to update the objects. Here is where I'm stuck. This is what I've tried and it doesn't work:
let a = arr => {
for(let i = 0; i < arr.length; i++) {
arr[i] = {
_curr: undefined,
_first: undefined,
_last: undefined,
get curr () { return this._curr },
set curr (v) { this._curr = v },
get first () { return this._first },
set first (v) { this._first = v },
get last () { return this._last },
set last (v) { this._last = v },
}
arr[i].curr = arr[i]
arr[i].first = arr[0]
arr[i].last = arr[arr.length - 1]
}
return arr
}
console.log(a([1,2]))
As you can see from the console output a([1,2])
produces
[ { curr: *first, first: *first, last: 2 },
{ curr: *second, first: *first, last: *second } ]
What I want is
[ { curr: *first, first: *first, last: *second } },
{ curr: *second, first: *first, last: *second } ]
How do I keep the behaviour enabled by using getters while also allowing the objects to be updatable?