Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/404.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 使用特殊逻辑将已排序数组的数组元素移动到另一个位置_Javascript_Sorting_Object_Logic - Fatal编程技术网

Javascript 使用特殊逻辑将已排序数组的数组元素移动到另一个位置

Javascript 使用特殊逻辑将已排序数组的数组元素移动到另一个位置,javascript,sorting,object,logic,Javascript,Sorting,Object,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:

我有这样一个分类收集:

 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值表示矩阵视图。对于示例模型,它如下所示:

 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}
 ];
[][][][]
[][][]
  []
  []
如果更容易理解的话,可以使用类似的结构reveal.js演示文稿

可以拖放元素([]表示一个元素)。 如果我将一个元素拖放到另一个元素,我将显示一个指示器,指示拖动的元素放置在何处(上方、下方、之前、之后)。需要collection中的数据来调用元素(缩略图)并将其发送回服务器

移动一个项目的功能应遵循以下逻辑: 我选择一个项目,例如,
{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}
  • “以下”表示
    {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编程或简化此逻辑的提示都会有所帮助

我创建了一个JSFIDLE,其中显示了主要思想,并对我遇到的问题给出了todo注释:
找到了一个似乎有效的解决方案:

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;
}
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}
];
//例
var movedItemIndex=3//将此值更改为要移动的项目
,movedItem=sortedCollection[movedItemIndex]
,movedItem=movedItem.id
,referenceItemIndex=6//将此值更改为要将项目移动到的项目引用位置
,referenceItem=sortedCollection[referenceItemIndex]
,referenceItemId=referenceItem.id
,relativePlacing=“上述”//第二个参考指示器(上、下、前、后)
sortedCollection=moveSortedCollectionItem(sortedCollection、MovedItemEx、referenceItem.x、referenceItem.y、relativePlacing);
sortedCollection=FixSortCollectionsUnmericalXandySequence(sortedCollection,movedItemId,referenceItemId);
console.dir(分类收集);
函数moveSortedCollectionItem(sortedCollection、itemIndex、refPosX、refPosY、relativePlace)
{    
开关(真)
{
案例(relativePlace==“高于”| | relativePlace==“之前”):
{
sortedCollection[itemIndex].x=refPosX
sortedCollection[itemIndex]。y=refPosY
打破
}
案例(相对位置=“以下”):
{
sortedCollection[itemIndex].x=refPosX
sortedCollection[itemIndex]。y=refPosY+1
打破
}           
案例(相对位置==“之后”):
{
sortedCollection[itemIndex].x=refPosX+1
sortedCollection[itemIndex]。y=refPosY
打破
}
}
返回分类收集;
}
函数fixsortCollectionsUnmericalXandySequence(sortedCollection、movedItemId、referenceItemId)
{    
//确保我们有正确的排序顺序
sortedCollection.sort(sortByXAndY);
//返回分类收集;
对于(变量i=0,len=sortedCollection.length;i