我正在尝试创建一个javascript函数,将数组右移x个单位。它必须保持数组大小相同,并且必须为从多维数组移出的元素调用unloadChunk。这是我目前的实施:
function shift(x, y) {
if (x > 0) {
for (var i = 0; i < chunks.length; i++) {
for (var j = chunks[i].length - 1; j >= 0; j--) {
if(j + x > chunks[i].length - 1 && chunks[i][j]) {
unloadChunk(i, j);
}
if (j < x) {
chunks[i][j] = null;
}
else {
chunks[i][j] = chunks[i][j - x];
}
}
}
}
else if (x < 0) {
for (var i = 0; i < chunks.length; i++) {
for (var j = 0; j < chunks[i].length; j++) {
if(j + x < 0 && chunks[i][j]) {
unloadChunk(i, j);
}
if (j - x >= chunks[i].length) {
chunks[i][j] = null;
}
else {
chunks[i][j] = chunks[i][j - x];
}
}
}
}
if (y > 0) {
for (var i = 0; i < chunks.length; i++) {
if (i + y >= chunks.length) {
for (var j = 0; j < chunks.length; j++) {
if(i - y < 0 && chunks[i][j]) {
unloadChunk(i, j);
}
chunks[i][j] = null;
}
}
else {
for (var j = 0; j < chunks.length; j++) {
if(i - y < 0 && chunks[i][j]) {
unloadChunk(i, j);
}
chunks[i][j] = chunks[i + y][j];
}
}
}
}
else if (y < 0) {
for (var i = chunks.length - 1; i >= 0; i--) {
if (i + y < 0) {
for (var j = 0; j < chunks.length; j++) {
if(i - y > chunks.length - 1 && chunks[i][j]) {
unloadChunk(i, j);
}
chunks[i][j] = null;
}
}
else {
for (var j = 0; j < chunks.length; j++) {
if(i - y > chunks.length - 1 && chunks[i][j]) {
unloadChunk(i, j);
}
chunks[i][j] = chunks[i + y][j];
}
}
}
}
}
如果您无法准确理解我想要的shift函数,请查看this fiddle并查看html输出。 我创建shift函数的尝试有效,但它有10个for循环。我的问题是,有没有更有效,更简洁的方法来做到这一点?
答案 0 :(得分:1)
此提案使用
Array#forEach
:访问每个项目
Array#map
:每个项目的返回值
Array#pop
:删除并返回最后一个元素
Array#push
:在末尾添加一个或多个元素
Array#shift
:删除并返回第一个元素
Array#unshift
:在开头添加一个或多个元素
为了更好的可见性,我将null
值替换为1000
,2000
,3000
和4000
。
function shift(x, y) {
while (x > 0) {
chunks.forEach(function (a) {
a.pop();
a.unshift(1000);
});
x--;
}
while (x < 0) {
chunks.forEach(function (a) {
a.shift();
a.push(2000);
});
x++;
}
while (y > 0) {
chunks.unshift(chunks.pop().map(function () { return 3000; }));
y--;
}
while (y < 0) {
chunks.push(chunks.shift().map(function () { return 4000; }));
y++;
}
}
function print(msg) {
document.body.innerHTML += '<p>' + msg + '</p>';
}
function printarr(arr) {
for (var i = 0; i < arr.length; i++) {
print(JSON.stringify(arr[i]))
}
}
var chunks = [[5, 3, 1], [9, 2, 5], [2, 3, 7]];
print("chunks: " + JSON.stringify(chunks));
shift(1, 0);
print("shifting right 1. chunks: "); printarr(chunks);
shift(-1, 0);
print("shifting left 1. chunks: "); printarr(chunks);
shift(0, 1);
print("shifting up 1. chunks: "); printarr(chunks);
shift(0, -1);
print("shifting down 1. chunks: "); printarr(chunks);
答案 1 :(得分:0)
您可以使用pop()
,push()
,shift()
,unshift()
数组方法
var chunks = [
[5, 3, 1],
[9, 2, 5],
[2, 3, 7]
];
function shiftDown(){
chuck.pop();
chuck.unshift(Array(3));
}
function shiftUp(){
chuck.shift();
chuck.push(Array(3));
}
function shiftRight(){
chuck.foreach(function(v){
v.pop();
v.unshift(null);
})
}
function shiftLeft(){
chuck.foreach(function(v){
v.shift();
v.push(null);
})
}
答案 2 :(得分:0)
如果正确解释问题,您可以使用{
"results": [
{
"address_components": [
{
"long_name": "43201",
"short_name": "43201",
"types": [
"postal_code"
]
},
{
"long_name": "Columbus",
"short_name": "Columbus",
"types": [
"locality",
"political"
]
},
{
"long_name": "Franklin County",
"short_name": "Franklin County",
"types": [
"administrative_area_level_2",
"political"
]
},
{
"long_name": "Ohio",
"short_name": "OH",
"types": [
"administrative_area_level_1",
"political"
]
},
{
"long_name": "United States",
"short_name": "US",
"types": [
"country",
"political"
]
}
],
"formatted_address": "Columbus, OH 43201, USA",
"geometry": {
"bounds": {
"northeast": {
"lat": 40.011147,
"lng": -82.9723898
},
"southwest": {
"lat": 39.976962,
"lng": -83.0250691
}
},
"location": {
"lat": 39.9929821,
"lng": -83.00122100000002
},
"location_type": "APPROXIMATE",
"viewport": {
"northeast": {
"lat": 40.011147,
"lng": -82.9723898
},
"southwest": {
"lat": 39.976962,
"lng": -83.0250691
}
}
},
"place_id": "ChIJ9Rz24rWOOIgR3EEuL2Ge4oo",
"types": [
"postal_code"
]
}
],
"status": "OK"
}
,Array.prototype.splice()
Array.prototype.forEach()
答案 3 :(得分:0)
当你在同一个数组上进行迭代时,改变一个数组并不是一个好主意。因此,将它必须为应该设置为null的元素调用unloadChunk
unloadChunk()
更改为不更改chunks
,但返回新值。
在我的情况下,我用新值填充所有空值。
那你为什么要先插入null
- 值呢?为什么不插入新值?
//one-dimensional shift
function shift(arr, offset, callback){
var i, j, len = arr.length;
if(len && (offset |= 0)){
typeof callback === "function" || (callback = function(v){return v});
if(offset < 0){
for(i=-offset,j=0; i<len;)arr[j++]=arr[i++];
while(j<len)arr[j]=callback(null,j++,arr);
}else if(offset){
for(i=len-offset,j=len; i>0;)arr[--j]=arr[--i];
for(i=0; i<j;++i)arr[i]=callback(null,i,arr);
}
}
return arr;
}
//two dimensional shift
function shift2d(matrix, offsetX, offsetY, callback){
var i, len = matrix.length, tmp, fn;
offsetY |= 0;
offsetX |= 0;
if(len && matrix[0].length && (offsetY || offsetX)){
typeof callback === "function" || (callback = function(v){return v});
fn = function(val,j){ return callback(null, [i,j], matrix) };
tmp = {length: matrix[0].length};
offsetY && shift(matrix, offsetY, function(){return tmp});
for(i = 0; i < len; ++i){
if(matrix[i] === tmp){
matrix[i] = Array.from(tmp,fn);
}else{
shift(matrix[i], offsetX, fn);
}
}
}
return matrix;
}
和代码:
var chunks = [[5, 3, 1], [9, 2, 5], [2, 3, 7]];
console.log(chunks);
console.log(shift2d(chunks, -1, 1));
console.log(shift2d(chunks, 1, -1, computeValue));
function computeValue(value, index, array){
console.log("value: %o index: %o, is chunks: %o", value, index, array === chunks);
//return the new value for this field
return JSON.stringify(index);
return Math.random();
//with ES6 array destructuring:
var [row,col] = index;
return row*3 + col;
}
shift()
和shift2d()
期望作为最后一个参数(
null
,仅出于一致性原因shift2d
,这是一系列索引(请查看array destructuring)