перебор массива с отступом
Добрый день,
Кто-нибудь знает как называется алгоритм который перебирает точки массива (матрицы) с отступом или по кругу не знаю как точно описать. Пример: МАССИВ [01, 02, 03, 04] [05, 06, 07, 08] [09, 10, 11, 12] [13, 14, 15, 16] На выходе перебора с шагом 1 (4 массива 2х2): #1 | #2 [01, 02] | [03, 04] [05, 06] | [07, 08] ----------+----------- #3 | #4 [09, 10] | [11, 12] [13, 14] | [15, 16] На выходе перебора с шагом 2 (1 массив 2х2): #1 [01, 03] [09, 11] На выходе перебора с шагом 3 (1 массив 2х2): #1 [01, 04] [13, 16] P.S. - обернул в [html] что бы не потерять отступы... не обращайте на это внимание P.P.S. - Для тех кто не знает как читать многомерные массивы добавил рамки |
так сделать сам я сдела но может что знает вариант получше а то этот какой то деревянный
var arr = [[1,2,3,4], [5,6,7,8], [9,10,11,12], [13,14,15,16] ], step = 1; for(i=0; i < 4; i=i+step*2) { for(j=0; j < 4; j=j+step*2) { var dot1 = arr[i][j], dot2 = arr[i][j+step], dot3 = arr[i+step][j], dot4 = arr[i+step][j+step]; alert("Section" + (i+j) + ": [" + dot1 + ", " + dot2 + ", " + dot3 + ", " + dot4 + "]"); } } |
array.slice()
|
laimas,
и как это поможет с двумерным массивом?! а если шаг будет не еденица а 3 тогда как?! |
Какая разница какой он у вас, вам же нужно получать срезы массива, что и делает slice(), указывайте необходимую длину, получайте, выводите, и также в цикле.
На php можно было бы и короче, одной функций можно разбить массив на массивы по N элементов сразу. |
не не мне нужны только крайние точки а не срезы... в этом то и вся разница
то есть если следовать примеру из Топика то если установить шаг 3, тогда вернется массив: [ [1,4] [13,16] ] конечно можно получить крайние точки но что делать с точками ниже?... хммм ну в общем да можно использовать слайс.. ок = спасибо ... но всеже это не совсем то |
Цитата:
[01, 02, 03, 04] ... На выходе перебора (4 массива 2х2): показать чистый исходник в новом окне Скрыть/показать номера строк печать кода с сохранением подсветки #1 #2 [01, 02] [03, 04] .... Что здесь тогда крайнее? ) |
Цитата:
массив №2 [[03,04][07,08]] массив №3 [[09,10][13,14]] массив №4 [[11,12][15,16]] Надеюсь тперь понятнее ) |
Изначально так и надо было написать. Ну и в чем проблема - зная вложения массива, получать по их индексам их срезы, четные и нечетные?
|
Цитата:
|
Цитата:
|
laimas,
не очень понимаю как очень просто брать эти срезы вариант решения function matrix(c, d) { for (var g = [], a = 0; a < d * d; a += c) { for (var f = [], e = [], b = 0; b < c; b++) e.push(a + b + 1); f.push(e); for (b = 0; b < c - 1; b++) e = e.map(function(a) { return a + d }), f.push(e); g.push(f); !a || (a + c) % d || (a += d * (c - 1)) } return g }; alert(JSON.stringify(matrix(2,4)))// матрицу 4 на 4 разбить 2 на 2 alert(JSON.stringify(matrix(3,9)))//этоn же вариант и для матрицы 9 на 9 на 3 на 3 ... matrix(3,9) |
var a = [ ['01', '02', '03', '04'], ['05', '06', '07', '08'], ['09', '10', '11', '12'], ['13', '14', '15', '16'] ], b = [], i, s = 2; for(i=0; i<a.length/2; i++) { b.push(a[i].slice(0, s), a[i+1].slice(0, s)); b.push(a[i].slice(s), a[i+1].slice(s)) } console.log(b) Ну естественно, если входной массив с произвольной длиной вложений и срезов которые нужно взять, то вычисляем эти условия. |
Кстати, рони, а то так и забуду. Интересная вещь совсем недавно приключилась с этим: $('selector')[0].
У заказчика несколько машин, одни работают под XP SP3, есть и семерки и одна под win 8.1. Возникла проблема - на одной из машин работающей под XP SP3 не загружаются файлы MS Office. Перед загрузкой клиент проверяет файл на разрешенный к загрузке тип (чисто сервис, дабы файлы). В реальности вывод ошибок сервера заблокирован и разрешен только в режиме отладки. JS-сценарий сжат. Спрашиваю, что в этом случае выдает браузер? Ответ - Ошибка. Зная что такого сообщения нет в коде, уточняю, что за ошибка. Ответ - Не разрешенный для загрузки тип файла. Это ближе к телу. И это только на одной машине происходит. Гадания и предположения, да еще на большие расстояния пользы не принесли, поэтому отдаю ему неупакованный JS со вставленными в предполагаемых проблемных местах вставках простых, чтобы он мне мог сообщать их, а я знал по ним узкое место. Вот тут и началось самое смешное - теперь браузер (любой) точно выдавал ошибку на строку в который и было получение DOM - $('selector')[0], не завершенный литерал, и хоть умри. А вот $('selector').get(0) без проблем. Но тогда почему это работает в сжатом JS!? :) После удалось узнать, что причиной является то, что JS на этой машине типы файлов MS Office получить не может, то есть files[n].type есть пустая строка. И именно только такие файлы, с остальными любыми проблем нет. Почему, так и не удалось выяснить, не имея машины под рукою "лечить" на расстоянии могут только кашпировские и т.п. :) |
laimas,
может проверку добавить if($('selector').length) ... и да замечал разницу с использованием min.js, до причины не дошёл ... просто ставил несжатую версию |
laimas,
вот что выдал лог [["01", "02"], ["05", "06"], ["03", "04"], ["07", "08"], ["05", "06"], ["09", "10"], ["07", "08"], ["11", "12"]] вроде нужно так: [[[1, 2], [5, 6]], [[3, 4], [7, 8]], [[9, 10], [13, 14]], [[11, 12], [15, 16]]] |
Цитата:
Цитата:
|
Цитата:
|
Цитата:
b.push([a[i].slice(0, s), a[i+1].slice(0, s)], [a[i].slice(s), a[i+1].slice(s)]) //[[["01", "02"], ["05", "06"]], [["03", "04"], ["07", "08"]], [["05", "06"], ["09", "10"]], [["07", "08"], ["11", "12"]]] в консоли, или не то? |
А, есть ошибка, смещение не проверяется, ну это тоже поправимо.
А я сперва даже не обратил внимание на выделенное красным :) |
вариант...
function split(src, dist, step, row, column) { if (row + step < src.length) { dist.push([ [src[row][column], src[row][column + step]], [src[row + step][column], src[row + step][column + step]], ]); if (column + step + 1 < src[0].length) { return split(src, dist, step, row, column + step + 1); } else { return split(src, dist, step, row + step + 1, 0); } } return dist; } var arr = [ [1,2,3,4], [5,6,7,8], [9,10,11,12], [13,14,15,16] ]; console.log(split(arr, [], 1, 0, 0)); console.log(split(arr, [], 3, 0, 0)); |
nerv_,
а что нужно поставить в аргументы split чтоб получить из var 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,26,27], [28,29,30,31,32,33,34,35,36], [37,38,39,40,41,42,43,44,45], [46,47,48,49,50,51,52,53,54], [55,56,57,58,59,60,61,62,63], [64,65,66,67,68,69,70,71,72 ], [73,74,75,76,77,78,79,80,81] ]; результат var arr=[[[1, 2, 3], [10, 11, 12], [19, 20, 21]], [[4, 5, 6], [13, 14, 15], [22, 23, 24]], [[7, 8, 9], [16, 17, 18], [25, 26, 27]], [[28, 29, 30], [37, 38, 39], [46, 47, 48]], [[31, 32, 33], [40, 41, 42], [49, 50, 51]], [[34, 35, 36], [43, 44, 45], [52, 53, 54]], [[55, 56, 57], [64, 65, 66], [73, 74, 75]], [[58, 59, 60], [67, 68, 69], [76, 77, 78]], [[61, 62, 63], [70, 71, 72], [79, 80, 81]]] |
var a = [ ['01', '02', '03', '04'], ['05', '06', '07', '08'], ['09', '10', '11', '12'], ['13', '14', '15', '16'] ], b = [], i, s = 2; for(i = 0; i<a.length; i += s) { b.push([a[i].slice(0, s), a[i+1].slice(0, s)], [a[i].slice(s), a[i+1].slice(s)]) } console.log(b) Маленько подумать, и для любой n-размерности в итерации нужно пройтись циклом n-раз в котором уже и push(). |
матрица разбить на квадраты
:write: :)
оставлю тут вариант на данный момент function matrix(c, d) { for (var h = [], a = 0; a < d * d; a += d * (c - 1)) for (var f = 0; f < d; f += c) { for (var g = [], e = [], b = 0; b < c; b++) e.push(a + b + 1); g.push(e); for (b = 0; b < c - 1; b++) e = e.map(function(a) { return a + d }), g.push(e); h.push(g); a += c } return h }; alert(JSON.stringify(matrix(2,4))) alert(JSON.stringify(matrix(3,9))) console.log(matrix(3,9)) |
Цитата:
как видишь, я руками в строке 03 добавляю фиксированный размер массива (2х2) на самом деле постановка задачи никакая) не понятно зачем вообще такие извращения |
:-? ... мда ... видимо сделать универсальный вариант, более никому не интересно :)
laimas, шаблон в цикле nerv_, шаблон но цикл заменён на рекурсию ![]() |
Цитата:
А в чем собственно проблема? Я понимаю так - задана размерность среза, которую нужно получить из массива. Получать данные нужно по смещению этой размерности среза, при чем элементы среза нужно получать не по строкам, а по колонкам массива. Итого - итерация внешнего цикла это постоянное смещение на размерность среза по строкам массива, а итерация внутреннего цикла, это постоянное смещение на размерность среза по колонкам массива. Во внутреннем цикле получаем срез, смещение которого определяется размерностью среза для колонок и строк массива. Лично меня жаба бы задавила гонять четыре цикла с долгими переборами и проверками. :) Я занимаюсь разработкой шрифта, вот закончу, тогда... А все таки беден JS на готовые функции для работы с массивами. |
спасибо
|
nerv_,
чутка сменил под свои нужды = спасибо, и что я тупанул и сразу не сделал рекурсию ?! - лох )) function split(src, st, r, c) { if(!st) return false; if (r + st < src.length && c + st < src[0].length) { console.log(st +"---------"+src[r][c]+","+ src[r][c + st]+","+src[r + st][c]+","+ src[r + st][c + st]); if (c + st +1 < src[0].length) { return split(src, st, r, ++c + st); } else { return split(src, st, ++r + st, 0); } } else split(src, st==1?0:Math.ceil(st/2), 0, 0); } var arr = [ [1,2,3,4], [5,6,7,8], [9,10,11,12], [13,14,15,16] ]; split(arr, 3, 0, 0); |
Цитата:
|
laimas, ну я бы не сказал что нужна НО рекурсия работает быстрее чем цикл - и в моем случае больше подходит именно она...
И должен уточнить что это если не ошибаюсь это единственный алгоритм который правильно работает с шагом (с разным шагом!!!) = у Рони было хорошее решение пока я не посчитал кооличество циклов)))) - 4 это уж слишком)) Так же мне нужна была адекватная работа с переменными (идем от простого = чем проще тем лучше) - в примерах рони было просто оочень много новых переменных особенно порадовало создание массива в перевом цикле (2го примера - см. выше)... за это отдельное СПАСИБО, РОНИ потому как я бы наверное так не ухитрился бы сделать так что это было хорошим "уроком"... Вам тоже СПАСИБО, но больше за дискут нежели за код - так как я все равно не согласен с применением slice в данном вопросе )))) Если я найду еще вариант решения задачи - обязательно отпишусь - если нет - закрою тему. )))) |
Цитата:
А если еще раз подумать нужна ли она там, где задачей предписано смещаться (нет в массивах отступов, есть смещения) на одинаковую размерность вниз и в ширину? алгоритм который правильно работает с шагом (с разным шагом!!!) slice() может получать срезы любой размерности и что замечательно, о чем не должна болеть голова, это то, что он вернет остаток, если размерность указана больше его. Чтобы обойти массив по вашим условиям не нужно никакой рекурсии и более того, чем больше заданная размерность смещения, тем меньше проходов в цикле будет требоваться. так как я все равно не согласен с применением slice в данном вопросе Вольному воля, мне все равно, хоть с карандашом в руках решайте. ) Но стоит заметить, и также о применении рекурсии, где она де-факто как стандарт и очень вредный, это получение дерева из базы. В этой задаче все наоборот - из данных лежащих в навал нужно получить на выходе упорядоченный массив. А ведь рекурсия в данном случае тоже совсем не нужна. |
Цитата:
1. я сделал "через" рекурсию потому, что хотел реализовать с помощью нее (спортивный интерес) 2. нужна ли здесь рекурсия? Нет, не нужна 3. быстрее ли работает рекурсия? Нет, не быстрей Цитата:
|
Цитата:
однако, должен прояснить ситуацию - мне нужено было решение для с++(наверное зря не сказал раньше, но не думал что такая "шумиха" поднимится), поэтому и выбрал рекурсию, если отойти от этого факта тогда да slice вполне можно было бы использовать, однако должен заметить что код laimas не справляется с поставленной задачей если сменить размер смещения например с 2 на 3 , код падает: var a = [ ['01', '02', '03', '04'], ['05', '06', '07', '08'], ['09', '10', '11', '12'], ['13', '14', '15', '16'] ], b = [], i, s = [B]2[/B]; for(i = 0; i<a.length; i += s) { b.push([a[i].slice(0, s), a[i+1].slice(0, s)], [a[i].slice(s), a[i+1].slice(s)]) } console.log(b) |
Цитата:
З.Ы. - а так же из-за того что я задавал много (на сегодня уже тупых) вопросов, когда только начанал изучать js, так что не считаю это трагедией З.З.Ы - плюс ко всему у меня соотношение вопрос\ответ наверное 50\1 тагда как у вас наверное 1\1000 )))) |
сравнил скорости.... мда...:
http://jsperf.com/matrix-reader-with-index-offset |
Цитата:
|
laimas,
так написали бы псевдокод - зачем людей вводить в замешательство, и подписали бы что это концепция - и все счасливы все думаю головой и доводят концепт до ума... как я уже говрил я благодарен за дискут, но слушать о том что я не думую головой это уже крайность, что бы использовать ваш "концепт" его надо в корне переделать - могли просто остановить на первой версии коцепта который вы предложили Цитата:
|
Информация к размышлению: не существует в природе готовой функции slice(), забыли, это в принципе как то радикально изменит концепцию получения необходимых элементов массива?
|
Готовое решение с for:
var arr = [], step = 5, // offset between choosen positions size = 11; // grid size ~ 11x11 for(i = 0; i < size; i++) { // fill array arr.push([]); var str = ''; for(j = 0; j < size; j++) { arr[i][j] = i * size + j; str+=addZero(''+arr[i][j], 3)+', '; } console.log(str); // draw array } for( i = 0 ; i + size * step < arr.length * size; i+=step) { // use ' i+=step' to start from last X pos (ex. 0-1, 1-2), else use ' i+=step+1' to reduce repetition (ex. 0-1, 2-3) var row = Math.floor(i / size), column = Math.floor(i % size); if( row == Math.floor((i + step) / size) && row % step == 0) { console.log( '-----'+ arr[row][column]+","+ arr[row][column + step]+","+ arr[row + step][column]+","+ arr[row + step][column + step] ); } } function addZero(str,length) { // add 0 to fill str length while(str.length < length) { str = '0'+str; } return str; } |
Часовой пояс GMT +3, время: 01:56. |