将排序数组的数组元素移动到具有特殊逻辑的另一个位置
Move an array element of a sorted array to another position with special logic
我有一个这样的排序集合:
var sortedCollection = [
{id: 3,x: 1,y: 1},
{id: 2,x: 1,y: 2},
{id: 1,x: 2,y: 1},
{id: 9,x: 2,y: 2},
{id: 5,x: 2,y: 3},
{id: 8,x: 2,y: 4},
{id: 7,x: 3,y: 1},
{id: 6,x: 3,y: 2},
{id: 4,x: 4,y: 1}
];
集合按 x 第一个排序,y 作为第二个排序值。
我的集合中的 x 和 y 值表示矩阵视图。使用示例模型,它看起来像这样:
[][][][]
[][][]
[]
[]
类似的结构揭示.js演示文稿使用,如果这更容易理解。
可以拖放元素([]代表一个元素(。如果我将一个元素拖放到另一个元素,我会显示一个指示器,其中放置了拖动的元素(上方、下方、之前、之后(。需要集合中的数据来重新处理元素(缩略图(并将其发送回服务器
移动一个项目的功能应遵循以下逻辑:我选择一个项目,例如 {x: 2,y: 2}
,我想在集合中移动。第二项是放置此元素的参考,例如 {x: 3, y: 2}
.应该可以将元素放在该元素的上方、下方、之前和之后。
这意味着对于我的两个示例值{x: 2,y: 2}
和{x: 3, y: 2}
引用放置 + 以下信息:
- "上面"表示
{x: 2,y: 2}
变得{x: 3, y: 2}
,之后的所有值和具有相同 x 值的重复值{x: 3, y: 2}
迭代 1 - "低于"表示
{x: 2,y: 2}
变得{x: 3, y: 3}
并且之后具有相同 x 值的所有值迭代 1
之前和之后的操作仅适用于具有 y: 1 的值(示例 {x: 2,y: 2}
和 {x: 3, y: 1}
(
- "before"表示
{x: 2,y: 2}
变得{x: 3, y: 1}
,{x: 3, y: 1}
变得{x: 4, y: 1}
,所有其他 x 值为 3 的对象变为 4 所有元素 x 值迭代 1 - "after"表示
{x: 2,y: 2}
变得{x: 4, y: 1}
并且{x: 3, y: 1}
保持不变,但所有 x 值大于 4 的元素都必须迭代 1
我希望我在描述我需要的东西时没有犯错。我无法管理它来处理填充空白或处理重复项以修复集合中的数字系列的所有情况。任何关于用 JavaScript 编程或简化此逻辑的提示都会有所帮助。
我创建了一个JSFiddle,它显示了主要思想,并在我卡住的位置上做了一个待办事项注释:http://jsfiddle.net/FrontEnds/69PXk/8/
有一个似乎有效的解决方案:
var sortedCollection = [
{id: 3,x: 1,y: 1},
{id: 2,x: 1,y: 2},
{id: 1,x: 2,y: 1},
{id: 9,x: 2,y: 2},
{id: 5,x: 2,y: 3},
{id: 8,x: 2,y: 4},
{id: 7,x: 3,y: 1},
{id: 6,x: 3,y: 2},
{id: 4,x: 4,y: 1}
];
// example case
var movedItemIndex = 3 // change this value to which item you want to move
,movedItem = sortedCollection[movedItemIndex]
,movedItemId = movedItem.id
,referenceItemIndex = 6 // change this value to which item reference where you want to move your item
,referenceItem = sortedCollection[referenceItemIndex]
,referenceItemId = referenceItem.id
,relativePlacing = "above"; // second reference indicator one of (above, below, before, after)
sortedCollection = moveSortedCollectionItem( sortedCollection, movedItemIndex, referenceItem.x, referenceItem.y, relativePlacing );
sortedCollection = fixSortCollectionsNumericalXAndYSequence( sortedCollection, movedItemId, referenceItemId );
console.dir( sortedCollection );
function moveSortedCollectionItem( sortedCollection, itemIndex, refPosX, refPosY, relativePlace )
{
switch( true )
{
case( relativePlace == "above" || relativePlace == "before" ):
{
sortedCollection[itemIndex].x = refPosX
sortedCollection[itemIndex].y = refPosY
break;
}
case( relativePlace == "below" ):
{
sortedCollection[itemIndex].x = refPosX
sortedCollection[itemIndex].y = refPosY + 1
break;
}
case( relativePlace == "after" ):
{
sortedCollection[itemIndex].x = refPosX + 1
sortedCollection[itemIndex].y = refPosY
break;
}
}
return sortedCollection;
}
function fixSortCollectionsNumericalXAndYSequence( sortedCollection, movedItemId, referenceItemId )
{
// make sure we have the right sort order
sortedCollection.sort( sortByXAndY );
// return sortedCollection;
for( var i = 0, len = sortedCollection.length; i < len; i++ )
{
if( i == 0 && (sortedCollection[i].x != 1 || sortedCollection[i].y != 1) )
{
// first one must have x: 1 and y; 1 in order to make the whole thing work
sortedCollection[i].x = 1;
sortedCollection[i].y = 1;
}
else if( typeof sortedCollection[i-1] != 'undefined' /* has previous item */ )
{
sortedCollection[i] = _replaceXAndYFromItemWithPreviousItem( sortedCollection[i-1], sortedCollection[i] );
}
}
return sortedCollection;
}
function _replaceXAndYFromItemWithPreviousItem( previousItem, currentItem )
{
// case: previous item x and current item x are the same
if( currentItem.x == previousItem.x )
{
// set current item y = previous item y + 1
currentItem.y = previousItem.y + 1;
}
// case: current item x is not previous item x and not previous item x + 1
else if( currentItem.x != previousItem.x && currentItem.x != previousItem.x + 1 )
{
// set current item x = previous item x + 1; set current item y = 1
currentItem.x = previousItem.x + 1;
currentItem.y = 1;
}
return currentItem;
}
function sortByXAndY( model1, model2 )
{
var a = parseInt( model1.x )
,b = parseInt( model2.x )
if( a == b )
{
var c = parseInt( model1.y )
,d = parseInt( model2.y );
return c - d;
}
return a - b;
}
http://jsfiddle.net/69PXk/17/
相关文章:
- 使用javascript和php,在单击图像时将其移动到另一个位置
- 创建从一个位置到另一个位置的路径动画
- 将HTML元素的位置更改为另一个位置javascript
- 在站点的另一个位置运行 java 脚本
- 当现有 Google 标记移动到另一个位置时,如何更新新的纬度和经度
- 使用jQuery单击时将元素移动/复制到另一个位置
- 将排序数组的数组元素移动到具有特殊逻辑的另一个位置
- 如何淡出图像,然后使其出现在jquery中的另一个位置
- 使用网页将本地文件复制到另一个位置
- 如何使用Grunt-contrib-copy将文件从一个位置单独复制到另一个位置
- 如何将 iframe 位置内部重定向到另一个位置
- 打印从当前位置到另一个位置的距离javascript
- 如何从元素中删除一些html,并将新的html附加到页面的另一个位置
- 在按钮单击事件中从另一个位置调用函数
- 如何将HTML表行拖放到另一个位置(在Jsp中)并将新位置(值)也保存在数据库(MySql)中
- 在OpenLayers 3中将要素从一个位置移动到另一个位置
- 使用JavaScript和html将图像和超链接从一个位置随机移动到另一个位置
- 移除Div并将其显示在另一个位置
- 使用d3将其转换到另一个位置
- 为什么当我试图拖拽太阳时,月亮会跳到另一个位置