查看一组项目是否放置在数组的特定部分内的最佳方法是什么?

时间:2011-08-31 18:29:09

标签: javascript arrays algorithm math mathematical-optimization

(请参阅下面的示例以完全理解我的要求)

我有一系列项目,我会根据用户的选择将其他项目放入并删除项目。此数组始终具有不超过30个项目的连续项目的“活动集”(当项目总数小于30时,它仅小于30,否则,它必须是满的)。用户可以更改活动集的开始。

我想知道的是什么是“最干净”的代码,并且最有效的方法来检查列表中添加/删除的新项目是否属于活动集,无论是部分还是全部? (此外,如果当前有10个项目,从而使活动设置项目0-9,并且他们在项目0前面添加10个项目 - 这使项目0成为项目10 - 那么我希望能够知道更改活动设置为新项目0到项目19)

实施例

//For this example, I'm making the active set be 10 items so I can write less
var activeSetLength = 10;

//The total set
var allItems = [ "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o" ];

//First item in active set (in this example, this makes "m" the last active item)
var activeSet = allItems.slice( 3, 3 + activeSetLength );

/*
 * Now imagine the user is trying to add items into our list, how best do I handle
 * figuring out whether to add them to the activeset list?.
 */
//Adding items into list at position 1 (so only some of these will now be in the active set)
addItems( [ "one", "two", "three", "four" ], 1 );

如果您需要更多解释,请告诉我,因为这可能不是最清楚的问题。谢谢!

注意:在“真实世界”中,我的activeSet实现为DOM节点,因此通过appendChild / insertBefore / removeChild 更改项目(添加此注释以便澄清)

1 个答案:

答案 0 :(得分:0)

我最后在处理比较之前/之后拍摄了一张快照,并按照以下方式做了一些事情:

addItems: function(items, insertAt)
{
    //The current items in the active set as an array
    var snapshot = this.getSnapshot();

    //Add to items array at position indicated
    this.saveItems( items, insertAt );

    //Change the items in active set
    this.updateActiveSet( snapshot );
}

updateActiveSet: function(oldSnapshot)
{
    //Take a new snapshot
    var currentSnapshot = this.getSnapshot();

    //Last dealt with item's index
    var lastHandled = -1;

    for ( var i = 0, length = oldSnapshot.length; i < length; i++ )
    {
        var old = oldSnapshot[ i ];
        var indexInCurrent = currentSnapshot.indexOf( old );

        //This item is still in the active set
        if ( indexInCurrent != -1 )
        {
            //We need to insert all current items before this
            for ( var iNew = lastHandled + 1; iNew < indexInCurrent; iNew++ ) activeSet.insertBefore( currentSnapshot[ iNew ], old );

            //Update last handled
            lastHandled = indexInCurrent;
        }

        //Remove from active set dom
        else activeSet.removeChild( old );
    }

    //Now append all new items that weren't inserted before a remaining item
    for ( var i = lastHandled + 1, length = currentSnapshot.length; i < length; i++ ) activeSet.appendChild( currentSnapshot[ i ] );
}

getSnapshot: function()
{
    return this.allItems.slice( this.startOfActiveSet, this.startOfActiveSet + this.activeSetLength );
}