How can i compare and combine 2 arrays using array functions of javascript or using lodash?
I have this initial array of dates for last 30 days.
[
'2022-12-11', '2022-12-12', '2022-12-13',
'2022-12-14', '2022-12-15', '2022-12-16',
'2022-12-17', '2022-12-18', '2022-12-19',
'2022-12-20', '2022-12-21', '2022-12-22',
'2022-12-23', '2022-12-24', '2022-12-25',
'2022-12-26', '2022-12-27', '2022-12-28',
'2022-12-29', '2022-12-30', '2022-12-31',
'2023-01-01', '2023-01-02', '2023-01-03',
'2023-01-04', '2023-01-05', '2023-01-06',
'2023-01-07', '2023-01-08', '2023-01-09',
'2023-01-10', '2023-01-11'
]
Then this is the second with count value.
[ [ '2023-01-09', 1 ], [ '2023-01-10', 3 ] ]
Now i have this code that compare and combine these array manually
let testData = [];
let k = 0;
dayList.forEach(o => {
let is_match = 0;
let frags = [];
submitted.forEach(i => {
if(o == i[0]){
is_match = 1;
frags = i;
}
});
testData[k] = [
(is_match == 1) ? frags[0] : o,
(is_match == 1) ? frags[1] : 0
];
k++;
});
console.log(testData);
this will result to...
[
[ '2022-12-11', 0 ], [ '2022-12-12', 0 ],
[ '2022-12-13', 0 ], [ '2022-12-14', 0 ],
[ '2022-12-15', 0 ], [ '2022-12-16', 0 ],
[ '2022-12-17', 0 ], [ '2022-12-18', 0 ],
[ '2022-12-19', 0 ], [ '2022-12-20', 0 ],
[ '2022-12-21', 0 ], [ '2022-12-22', 0 ],
[ '2022-12-23', 0 ], [ '2022-12-24', 0 ],
[ '2022-12-25', 0 ], [ '2022-12-26', 0 ],
[ '2022-12-27', 0 ], [ '2022-12-28', 0 ],
[ '2022-12-29', 0 ], [ '2022-12-30', 0 ],
[ '2022-12-31', 0 ], [ '2023-01-01', 0 ],
[ '2023-01-02', 0 ], [ '2023-01-03', 0 ],
[ '2023-01-04', 0 ], [ '2023-01-05', 0 ],
[ '2023-01-06', 0 ], [ '2023-01-07', 0 ],
[ '2023-01-08', 0 ], [ '2023-01-09', 1 ],
[ '2023-01-10', 3 ], [ '2023-01-11', 0 ]
]
As you can see the date 2023-01-09 and 2023-01-10 have values then the rest has 0 values.
Which is what i expected, i'm just new in coding a pure javascript application, i just translated my PHP code to javascript.
Now is there a way that this code may be simplified using array functions of javascript or using lodash?
Here's an approach, we first create a map with the date as key and count as value and then use this map to generate the result
const dates=["2022-12-11","2022-12-12","2022-12-13","2022-12-14","2022-12-15","2022-12-16","2022-12-17","2022-12-18","2022-12-19","2022-12-20","2022-12-21","2022-12-22","2022-12-23","2022-12-24","2022-12-25","2022-12-26","2022-12-27","2022-12-28","2022-12-29","2022-12-30","2022-12-31","2023-01-01","2023-01-02","2023-01-03","2023-01-04","2023-01-05","2023-01-06","2023-01-07","2023-01-08","2023-01-09","2023-01-10","2023-01-11",];
const count=[["2023-01-09",1],["2023-01-10",3]];
const countMap = count.reduce((acc, [date, count]) => {
acc[date] = count;
return acc;
}, {});
const result = dates.map((date) => [date, countMap[date] || 0]);
console.log(result)
You can simply run any loop and find the index of the current element in the submitted array and check if exist then assign date otherwise assign 0 to the array
var dayList = ['2022-12-11', '2023-01-10', '2023-01-09']
var submitted = [ [ '2023-01-09', 1 ], [ '2023-01-10', 3 ] ]
var testData = []
dayList.filter(o => {
const exist = submitted.find(e => e.indexOf(o) != -1)
if(exist){
testData.push([o, exist[1]])
} else {
testData.push([o, 0])
}
});
console.log("your data=", testData)
Related
I'm new to Javascript. I'm trying to get the Math.max(...arr1[i][1]) of the array(arr1), only when it is matched with the 2nd array(arr2). Then, push it on the array(arr3) and the result should have no duplicate values.
I tried iterating both arrays(arr1 & arr2) then used an "if statement" for matching them.
var arr1 = [ [ 'abandon', -2 ],
[ 'abandon', 1 ],
[ 'abandon', -2 ],
[ 'abduct', 1 ],
[ 'abduct', -2 ],
[ 'abduct', -2 ],
[ 'abhor', -3 ],
[ 'abhor', 1 ],
[ 'abhor', -1 ],
[ 'abil', 2 ],
[ 'abil', 4 ] ];
var arr2 = [ [ 'abandon' ],
[ 'abil' ],
[ 'abhor' ],
[ 'abduct' ],
['test'],
['hey'],
['testAgain'],
['array']];
var arr3 = [];
const mapping = arr2.map(word => {
return word
})
for(var i = 0; i < arr1.length; i++){
if(arr1[i][0] === mapping){
arr3.push(Math.max(...arr1[i][1]))
}
}
let arr4 = [...new Set(arr3)]
//example result:
var arr4 = [[abandon, -2],
[abduct, -2],
[abhor, -3],
[abil, 4]... and so on]
I know I'm doing something wrong, and I'm out of option. Need help.
You can better use a Set instead of an array like arr2 directly for finding a match as it will be constant time lookup in case of a Set.
Then use a Array.prototype.filter to filter the array arr1 and get those arrays which are in arr2.
Lastly Array.prototype.reduce would help you make an object with the keys being the words and values being the largest value for that word in the arr1 and you could use Object.entries from that object returned from reduce to get the data in the form of a 2-D array:
var arr1 = [ [ 'abandon', -2 ],
[ 'abandon', 1 ],
[ 'abandon', -2 ],
[ 'abduct', 1 ],
[ 'abduct', -2 ],
[ 'abduct', -2 ],
[ 'abhor', -3 ],
[ 'abhor', 1 ],
[ 'abhor', -1 ],
[ 'abil', 2 ],
[ 'abil', 4 ] ];
var arr2 = [ [ 'abandon' ],
[ 'abil' ],
[ 'abhor' ],
[ 'abduct' ],
['test'],
['hey'],
['testAgain'],
['array']];
var lookup = new Set(arr2.flat());
var mapping = arr1.filter(([word, val]) => lookup.has(word));
var data = Object.entries(mapping.reduce((acc, o, i) => {
if(acc[o[0]]){
acc[o[0]] = Math.max(o[1], acc[o[0]]);
}else{
acc[o[0]] = o[1];
}
return acc;
},{}));
console.log(data);
EDIT
Form your comment I assume that you are using a older version of node runtime where flat() is not present in the Array.prototype. So you can use the edited snippet below:
var arr1 = [ [ 'abandon', -2 ],
[ 'abandon', 1 ],
[ 'abandon', -2 ],
[ 'abduct', 1 ],
[ 'abduct', -2 ],
[ 'abduct', -2 ],
[ 'abhor', -3 ],
[ 'abhor', 1 ],
[ 'abhor', -1 ],
[ 'abil', 2 ],
[ 'abil', 4 ] ];
var arr2 = [ [ 'abandon' ],
[ 'abil' ],
[ 'abhor' ],
[ 'abduct' ],
['test'],
['hey'],
['testAgain'],
['array']];
//flatten using Array.prototype.concat
var lookup = new Set([].concat.apply([], arr2));
//If Set doesn't work use the array, but this will not be a constant time lookup
//var lookup = [].concat.apply([], arr2);
var mapping = arr1.filter(([word, val]) => lookup.has(word));
//If you are not using Set and going with an array, use Array.prototype.includes, so search won't be O(1)
//var mapping = arr1.filter(([word, val]) => lookup.includes(word));
var data = Object.entries(mapping.reduce((acc, o, i) => {
if(acc[o[0]]){
acc[o[0]] = Math.max(o[1], acc[o[0]]);
}else{
acc[o[0]] = o[1];
}
return acc;
},{}));
console.log(data);
I would do with as few loops as possible.
var arr1 = [ [ 'abandon', -2 ], [ 'abandon', 1 ], [ 'abandon', -2 ], [ 'abduct', 1 ], [ 'abduct', -2 ], [ 'abduct', -2 ], [ 'abhor', -3 ], [ 'abhor', 1 ], [ 'abhor', -1 ], [ 'abil', 2 ], [ 'abil', 4 ] ];
var arr2 = [ [ 'abandon' ], [ 'abil' ], [ 'abhor' ], [ 'abduct' ], ['test'], ['hey'], ['testAgain'], ['array']];
function getHighestResults(dataArr, filterArr) {
var name = ''; // higher readability in code and created outside
var number = -1; // for loops to avoid creating variables inside of them
function existsInObject(obj, name) {
return obj.hasOwnProperty(name);
}
function filterBasedOn(arr, obj) {
var filteredArr = [];
for (let i = 0; i < arr.length; i++) {
name = arr[i][0];
if (existsInObject(obj, name)) {
filteredArr.push([name, obj[name]]);
}
}
return filteredArr;
}
function getHighestValuesAsObj(arr) {
var dataObj = {};
for (let i = 0; i < arr.length; i++) {
name = arr[i][0];
number = arr[i][1];
if (!existsInObject(dataObj, name) || dataObj[name] < number) {
dataObj[name] = number;
}
}
return dataObj;
}
return filterBasedOn(filterArr, getHighestValuesAsObj(dataArr));
}
console.log(getHighestResults(arr1, arr2));
I am trying to format a string to produce a new string in the correct format:
I have the following strings (left) which should be formatted to match (right):
[ 'xx9999', 'XX-99-99' ],
[ '9999xx', '99-99-XX' ],
[ '99xx99', '99-XX-99' ],
[ 'xx99xx', 'XX-99-XX' ],
[ 'xxxx99', 'XX-XX-99' ],
[ '99xxxx', '99-XX-XX' ],
[ '99xxx9', '99-XXX-9' ],
[ '9xxx99', '9-XXX-99' ],
[ 'xx999x', 'XX-999-X' ],
[ 'x999xx', 'X-999-XX' ],
[ 'xxx99x', 'XXX-99-X' ],
[ 'x99xxx', 'X-99-XXX' ],
[ '9xx999', '9-XX-999' ],
[ '999xx9', '999-XX-9' ]
I have tried the following but cannot get it to work correctly:
const formatLp = (userInput) => {
if (userInput) {
return userInput.toUpperCase().match(/[a-z]+|[^a-z]+/gi).join('-');
}
}
This works for some of them, such as 99xxx9 but not others such as xx9999
any help would be appreciated.
Use .replace twice - once to insert a - between 4 repeated digits/non-digits, and once to insert a - between digits and alphabetical characters:
const arr = [
[ 'xx9999', 'XX-99-99' ],
[ '9999xx', '99-99-XX' ],
[ '99xx99', '99-XX-99' ],
[ 'xx99xx', 'XX-99-XX' ],
[ 'xxxx99', 'XX-XX-99' ],
[ '99xxxx', '99-XX-XX' ],
[ '99xxx9', '99-XXX-9' ],
[ '9xxx99', '9-XXX-99' ],
[ 'xx999x', 'XX-999-X' ],
[ 'x999xx', 'X-999-XX' ],
[ 'xxx99x', 'XXX-99-X' ],
[ 'x99xxx', 'X-99-XXX' ],
[ '9xx999', '9-XX-999' ],
[ '999xx9', '999-XX-9' ]
];
arr.forEach(([str]) => {
const result = str.toUpperCase()
.replace(/\d{4}|\D{4}/, substr => `${substr.slice(0, 2)}-${substr.slice(2)}`)
.replace(/[a-z]{4}|\d(?=[a-z])|[a-z](?=\d)/gi, '$&-');
console.log(result);
});
You can also do it by matching and then joining - match 3 non-digits, or 3 digits, or 1-2 non-digits, or 1-2 digits:
const arr = [
[ 'xx9999', 'XX-99-99' ],
[ '9999xx', '99-99-XX' ],
[ '99xx99', '99-XX-99' ],
[ 'xx99xx', 'XX-99-XX' ],
[ 'xxxx99', 'XX-XX-99' ],
[ '99xxxx', '99-XX-XX' ],
[ '99xxx9', '99-XXX-9' ],
[ '9xxx99', '9-XXX-99' ],
[ 'xx999x', 'XX-999-X' ],
[ 'x999xx', 'X-999-XX' ],
[ 'xxx99x', 'XXX-99-X' ],
[ 'x99xxx', 'X-99-XXX' ],
[ '9xx999', '9-XX-999' ],
[ '999xx9', '999-XX-9' ]
];
arr.forEach(([str]) => {
const result = str.toUpperCase()
.match(/[a-z]{3}|\d{3}|[a-z]{1,2}|\d{1,2}/gi)
.join('-');
console.log(result);
});
I've just implemented this using Stack. Here is the function. You just need to pass the string to this function.
const convert = (str) => {
let stack = str.split('').reduce((newArr, char, index) => {
if(index !== 0 && newArr[newArr.length-1] !== char) {
newArr.push('-');
newArr.push(char);
return newArr;
} else {
newArr.push(char);
return newArr;
}
},[])
return stack.join('').toUpperCase();
}
// Here you can check this in action
const convert = (str) => {
let stack = str.split('').reduce((newArr, char, index) => {
if(index !== 0 && newArr[newArr.length-1] !== char) {
newArr.push('-');
newArr.push(char);
return newArr;
} else {
newArr.push(char);
return newArr;
}
},[])
return stack.join('').toUpperCase();
}
const strings = [ 'xx9999','9999xx','99xx99','xx99xx','xxxx99','99xxxx','99xxx9','9xxx99','xx999x','x999xx','xxx99x','x99xxx','9xx999','999xx9',];
strings.map(string => console.log(convert(string)))
My data looks like:
[ [ '0s', '0.200s' ],
[ '0.200s', '0.600s' ],
[ '1.600s', '2.500s' ],
[ '3.500s', '3.900s' ],
[ '3.900s', '4.400s' ],
[ '4.400s', '4.600s' ],
[ '4.600s', '4.700s' ],
[ '4.700s', '5.200s' ],
[ '5.200s', '5.400s' ],
[ '5.400s', '5.800s' ],
[ '5.800s', '6.100s' ],
[ '6.100s', '6.800s' ],
[ '6.800s', '7s' ],
[ '7s', '7.300s' ],
[ '7.300s', '7.500s' ]
]
The first element ends at 0.200s which is where the second element begins. So I want those 2 to combine to be ['0s', '0.600s'].
The next element doesn't start where this one ends, so it should continue on. Ultimately, the result should look like:
[ [ '0s', '0.600s' ],
[ '1.600s', '2.500s' ],
[ '3.500s', '7.500s' ]
]
I am trying to do it recursively, but it's giving errors. Here's my function:
function combineStartsEnds(timecodes) {
if (timecodes[0][1] === timecodes[1][0]) {
let combined = [
[timecodes[0][0], timecodes[1][1]]
].concat(_.slice(timecodes, 2));
return combineStartsEnds(combined);
} else {
return timecodes[0].concat(combineStartsEnds(_.slice(timecodes, 1)));
}
};
This gives an error:
TypeError: Cannot read property '0' of undefined
Any ideas on how to accomplish this?
You are missing brackets here, this:
return timecodes[0].concat(...)
must be:
return [timecodes[0]].concat(...)
Additionally you need a base case to end the recursion:
function combineStartsEnds(timecodes) {
if(!timecodes.length) return [];
How I would do that:
function combineStartsEnds(timecodes) {
const result = []; let previous = [];
for(const [start, end] of timecodes) {
if(start === previous[/*end*/ 1]) {
previous[/*end*/ 1] = end;
} else {
result.push(previous = [start, end]);
}
}
return result;
}
You can also do this with reduce.
const times = [ [ '0s', '0.200s' ],
[ '0.200s', '0.600s' ],
[ '1.600s', '2.500s' ],
[ '3.500s', '3.900s' ],
[ '3.900s', '4.400s' ],
[ '4.400s', '4.600s' ],
[ '4.600s', '4.700s' ],
[ '4.700s', '5.200s' ],
[ '5.200s', '5.400s' ],
[ '5.400s', '5.800s' ],
[ '5.800s', '6.100s' ],
[ '6.100s', '6.800s' ],
[ '6.800s', '7s' ],
[ '7s', '7.300s' ],
[ '7.300s', '7.500s' ]
];
const merged = times.reduce((acc, [t3, t4]) => {
const [t1, t2] = acc[acc.length - 1] || [null, null];
if (t2 === t3) {
acc.pop();
acc.push([t1, t4]);
} else {
acc.push([t3, t4]);
}
return acc;
}, []);
console.log(merged);
You can also try below method to get your desired result.
(1) Flatten the array, you will get
arr.flat()
["0s", "0.200s", "0.200s", "0.600s", "1.600s", "2.500s", "3.500s", "3.900s", "3.900s", "4.400s", "4.400s", "4.600s", "4.600s", "4.700s", "4.700s", "5.200s", "5.200s", "5.400s", "5.400s", "5.800s", "5.800s", "6.100s", "6.100s", "6.800s", "6.800s", "7s", "7s", "7.300s", "7.300s", "7.500s"]
(2) Filter and remove elements if same exists before and after it's position, you will get
arr.flat().filter((d,i,c) => d != c[i-1] && d != c[i+1])
["0s", "0.600s", "1.600s", "2.500s", "3.500s", "7.500s"]
(3) Reduce the above result to the format you need
arr.flat()
.filter((d,i,c) => d != c[i-1] && d != c[i+1])
.reduce((res, d, i, c) => (i%2 == 0 && res.push([d, c[i+1]]) , res) , [])
[["0s", "0.600s"]
["1.600s", "2.500s"]
["3.500s", "7.500s"]]
How about using a Map():
const data = [
['0s', '0.200s'],
['0.200s', '0.600s'],
['1.600s', '2.500s'],
['3.500s', '3.900s'],
['3.900s', '4.400s'],
['4.400s', '4.600s'],
['4.600s', '4.700s'],
['4.700s', '5.200s'],
['5.200s', '5.400s'],
['5.400s', '5.800s'],
['5.800s', '6.100s'],
['6.100s', '6.800s'],
['6.800s', '7s'],
['7s', '7.300s'],
['7.300s', '7.500s']
];
var data_map = new Map(data);
for (var [key, value] of data_map) {
while (data_map.has(value)) {
var new_value = data_map.get(value);
data_map.set(key, new_value);
data_map.delete(value);
value = new_value;
}
}
data_map.forEach((value, key) => console.log(`[${key}, ${value}]`));
You could reduce the array with a single loop by checking the values and update either the last array or push a new array to the result set.
var data = [['0s', '0.200s'], ['0.200s', '0.600s'], ['1.600s', '2.500s'], ['3.500s', '3.900s'], ['3.900s', '4.400s'], ['4.400s', '4.600s'], ['4.600s', '4.700s'], ['4.700s', '5.200s'], ['5.200s', '5.400s'], ['5.400s', '5.800s'], ['5.800s', '6.100s'], ['6.100s', '6.800s'], ['6.800s', '7s'], ['7s', '7.300s'], ['7.300s', '7.500s']],
combined = data.reduce((r, [a, b]) => {
var last = r[r.length - 1];
if (last && a === last[1]) {
last[1] = b;
} else {
r.push([a, b]);
}
return r;
}, []);
console.log(combined);
.as-console-wrapper { max-height: 100% !important; top: 0; }
One way to do it using recursion –
const start = ([ a, b ]) =>
a
const end = ([ a, b ]) =>
b
const join = ([ a, b, ...rest ]) =>
// base: no `a`
a === undefined
? []
// inductive: some `a`
: b === undefined
? [ a ]
// inductive: some `a` and some `b` (joinable)
: end (a) === start (b)
? join ([ [ start (a), end (b) ], ...rest ])
// inductive: some `a` and some `b` (non-joinable)
: [ a, ...join ([ b, ...rest ]) ]
const data =
[ [ '0s', '0.200s' ]
, [ '0.200s', '0.600s' ]
, [ '1.600s', '2.500s' ]
, [ '3.500s', '3.900s' ]
, [ '3.900s', '4.400s' ]
, [ '4.400s', '4.600s' ]
, [ '4.600s', '4.700s' ]
, [ '4.700s', '5.200s' ]
, [ '5.200s', '5.400s' ]
, [ '5.400s', '5.800s' ]
, [ '5.800s', '6.100s' ]
, [ '6.100s', '6.800s' ]
, [ '6.800s', '7s' ]
, [ '7s', '7.300s' ]
, [ '7.300s', '7.500s' ]
]
console.log (join (data))
// [ [ '0s', '0.600s' ]
// , [ '1.600s', '2.500s' ]
// , [ '3.500s', '7.500s' ]
// ]
Can someone explain to me why the following happens in Javascript Console (Node 7.2.0):
Array in example I has different behavior than example II and III
EXAMPLE I
> var x = new Array(3).fill(new Array(2).fill(0))
> x
[ [ 0, 0 ], [ 0, 0 ], [ 0, 0 ] ]
> x[0][0] = 1;
> x
[ [ 1, 0 ], [ 1, 0 ], [ 1, 0 ] ]
EXAMPLE II
> var y = [...new Array(3)].map(()=>{return [...new Array(2)].map(()=>0)})
> y
> [ [ 0, 0 ], [ 0, 0 ], [ 0, 0 ] ]
> y[0][0] = 1
> [ [ 1, 0 ], [ 0, 0 ], [ 0, 0 ] ]
EXAMPLE III
> var y = []
> y.push([ 0, 0 ])
> y.push([ 0, 0 ])
> y.push([ 0, 0 ])
> y
> [ [ 0, 0 ], [ 0, 0 ], [ 0, 0 ] ]
> y[0][0] = 1
> [ [ 1, 0 ], [ 0, 0 ], [ 0, 0 ] ]
It seems that different ways to initialize array will cause different behaviors of an array. I'm confused and thank you in advance.
array.fill() returns the modified array, so you're filling an array with multiple references to the same array. That is why when you modify it in one place, it automatically shows up in the other places.
The first example is equivalent to doing something like:
var arr = [ 0, 0 ];
var x = [ arr, arr, arr ];
The reason for the difference is that in JS, objects (including arrays) are not copied, they are linked. In example I, you fill the array with a single array.
> var x = new Array(3).fill(new Array(2).fill(0))
// You have filled x with three links to the same array
> x
[ [ 0, 0 ], [ 0, 0 ], [ 0, 0 ] ]
> x[0][0] = 1;
// You have now modified the actual array, this change is reflected in all the links to it.
> x
[ [ 1, 0 ], [ 1, 0 ], [ 1, 0 ] ]
What you are doing is the same as doing:
var a = [ 0, 0 ]
var x = [ a, a, a ]
OR
var a = [ 0, 0 ]
var x = []
x.push(a)
x.push(a)
x.push(a)
BTW, using new Array() is generally a bad practice. There is no benefit over the array literal syntax. Also, using new Array(n) makes "empty slots" in your array, which is very odd and can cause problems in your programs if you don't fill all the slots.
hi pretty new to javascript.I am pretty confused in spliting my array value
console.log(arr)//[ [ [ 10, 0 ] ], [ [ 8, 0 ] ], [ [ 8, 0 ] ], [ [ 5, 2 ] ] ]
var line = "";
arr.forEach(e => {
e.forEach(f => line += "[" + f.join(",") + "],");
});
console.log(line);//[10,0],[8,0],[8,0],[5,2],
But i want my ouptput like this to do matrix addition
console.log(line);//[[10,0],[8,0],[8,0],[5,2]]
You can use map() for this.
var arr = [ [ [ 10, 0 ] ], [ [ 8, 0 ] ], [ [ 8, 0 ] ], [ [ 5, 2 ] ] ];
var result = arr.map(function(a) {
return a[0];
});
console.log(result)
You could do this by changing where the join happens and pre/app-ending some square brackets, e.g.
var line = arr.map(e => e.map(f => f.join(",")));
console.log('[' + line.join('],[') + ']');
// [10,0],[8,0],[8,0],[5,2]
I do have to ask though, why are you getting back a set of arrays each with a single value? Is it possible to avoid getting a dataset like that in the first place? You could avoid the double map/foreach that way.
For instance if you had one level less nesting in your source array the map line would become a little simpler
var arr = [ [ 10, 0 ], [ 8, 0 ], [ 8, 0 ], [ 5, 2 ] ];
var line = arr.map(f => f.join(","));
console.log('[' + line.join('],[') + ']');
This is of course if you want to specifically output the string for the array matrix, if you just wanted a flatter version of your original array then you could do:
var newList = arr.map(f => f[0]);
// [ [ 10, 0 ], [ 8, 0 ], [ 8, 0 ], [ 5, 2 ] ]