I have a function called Action
which receives an array parameter like this.
[
['X','','O'],
['O','','O'],
['X','X','']
]
I want this function to return an array like this where each empty section of the previous array is filled individually with a specific value, e.g Y
.
[
[
['','Y',''],
['','',''],
['','','']
],
[
['','',''],
['','Y',''],
['','','']
],
[
['','',''],
['','',''],
['','','Y']
]
]
I know I can do that with forEach
but it needs nested forEach
which I think isn't very optimal. Is there any better way of doing that?
CodePudding user response:
This should work:
let arr = [
['X','','O'],
['O','','O'],
['X','X','']
]
let res = []
arr.map((item, index)=>{
item.map((sub, indx) =>{
if(sub === ""){
let array_=
[
['','',''],
['','',''],
['','','']
];
array_[index][indx] = "Y";
res.push(array_)
}
})
})
console.log(res)
CodePudding user response:
You could avoid nesting loops with the following steps
- flatten the matrix into a 1-d array
- get the indices of the empty sections
- create new flatten 1-d arrays with empty indices from previous result marked as
'Y'
- transform flatten 1-d arrays back to 3x3 matrix
const arr = [
["X", "", "O"],
["O", "", "O"],
["X", "X", ""],
]
const res = arr
.flat() // flatten the array
.map((section, i) => [section, i])
.filter(([section, _]) => section === "")
.map(([_, i]) => i) // get the indices of empty sections
.map(sectionIdx =>
Array.from({ length: 9 }, (_, i) => (i === sectionIdx ? "Y" : ""))
) // create new flattened array with empty indices marked as 'Y'
.map(flattenedArr => [
flattenedArr.slice(0, 3),
flattenedArr.slice(3, 6),
flattenedArr.slice(6, 9),
]) // turn back flatten array into 3x3 matrix
console.log(res)