简体   繁体   中英

How to loop outwards from a point in an array?

I have the following array:

let arr = [ 1,  2,  3,  4,  5,
            6,  7,  8,  9, 10,
           11, 12, 13, 14, 15,
           16, 17, 18, 19, 20,
           21, 22, 23, 24, 25 ]

How will I write a function, which will loop through the elements adjacent to it. For example, if I input 13, it will go through 7,8,9,12,14,17,18 and 19 and then the elements adjacent to them ie 1,2,3,4,5,6,10,11,15,16,20,21,22,23 and 25.

I have tried looping separately. that is +5,-5,+6,-6,+4,-4,+1 and -1. Unfortunately, I haven't been able to make it work.

Also, if any of the inputs are corner then the rest of the elements will be looped through. For example, if 1 is given then 2,6 and 7 and then 3,8,13,12,11 and so on. In essence all elements should be looped through.

Get the size of the array and row & column of the current number. Then get all indexes from [row-1,col-1] to [row+1,col+1] . Some of the values could be negative for border elements. So, exclude those

 function surronding(array, n) { const size = Math.sqrt(array.length), index = n - 1, row = Math.floor(index / size), col = index % size, output = [] for (let x = row - 1; x <= row + 1; x++) { for (let y = col - 1; y <= col + 1; y++) { if (x === row && y === col) // current continue; if (x < 0 || y < 0 || x >= size || y >= size) // out of range continue; output.push(arr[x * size + y]) } } return output; } const arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25] console.log(...surronding(arr, 13)) console.log(...surronding(arr, 1)) console.log(...surronding(arr, 5))

One way could be to do a bucket sort of the values, where there is a bucket for each possible distance of the value to the given "center" value, and then output the buckets in order of distance:

 function solve(n, root) { const x = --root % n; const y = (root - x) / n; const result = Array.from({length: n}, () => []); for (let i = 0; i < n*n; i++) { if (i == root) continue; result[Math.max(Math.abs(x - i % n), Math.abs(y - Math.floor(i / n)))].push(i+1); } return result.flat(); } console.log(solve(5, 13));

You first need to transpose your value to line, column position.

 const arr = [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25 ] function getAdjacents(number, arr) { let sQ = Math.sqrt(arr.length), n = number -1 // first position is zero, C_ = n % sQ // column position, R_ = (n - C_) / sQ // row position; return Array(3).fill().reduce((z,_,r)=> [...z,...Array(3).fill().map((_,c)=>[r+R_-1,c+C_-1])],[]).reduce((res,[rx,cx])=> { if ( rx>=0 && cx>=0 && rx<sQ && cx<sQ && (rx.=R_ || cx,=C_) ) res.push((rx*sQ)+cx+1) return res },[]) } console,log(13. '->'. .,.getAdjacents(13, arr) ) //-> 7 8 9 12 14 17 18 19 console,log( 1. '->'. .,.getAdjacents( 1, arr) ) //-> 2 6 7 console,log( 5. '->'. .,.getAdjacents( 5, arr) ) //-> 4 9 10 console,log(22. '->'. .,.getAdjacents(22, arr) ) //-> 16 17 18 21 23
 .as-console-wrapper {max-height: 100%;important:top;0;}

You could take an approach with the length of the sides and an offset for the pivot element. as result, you get an index for a linear array.

 const getAdjacent = (length, startI, startJ, offset = 0) => { const indices = []; offset++; for (let i = startI - offset; i <= startI + offset; i++) { for (let j = startJ - offset; j <= startJ + offset; j++) { if ( i < 0 || i >= length || j < 0 || j >= length || (i;== startI - offset && i.== startI + offset && j;== startJ - offset && j;== startJ + offset) ) continue; indices.push(i * length + j). } } return indices. }. console,log(,,;getAdjacent(5. 2. 2. 0)). console,log(,,;getAdjacent(5, 2, 2, 1));

I'm guessing that this fundamentally works the same way as @trincot's answer but I already had written most of it, hopefully it's okay to still post it.

 const row_col_for_number = (square_side_size, number) => [ parseInt((number - 1) / square_side_size) + 1, ((number - 1) % square_side_size) + 1 ]; const biggest_row_col_diff = ([a_row, a_col], [b_row, b_col]) => Math.max(Math.abs(a_row - b_row), Math.abs(a_col - b_col)); const distance_to_start = (square_side_size, start_row_col, number) => biggest_row_col_diff( start_row_col, row_col_for_number(square_side_size, number) ); const sort_square_adjacency = (square_side_size, start_row_col) => (a, b) => distance_to_start(square_side_size, start_row_col, a) - distance_to_start(square_side_size, start_row_col, b); const doit = (square_side_size, start_number) => new Array(square_side_size * square_side_size).fill(0).map((_, i) => i + 1).sort( sort_square_adjacency( square_side_size, row_col_for_number(square_side_size, start_number) ) ).slice(1); console.log(...doit(5, 1)); console.log(...doit(5, 13));

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM