首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >何时使用数组,何时使用对象?

何时使用数组,何时使用对象?
EN

Stack Overflow用户
提问于 2016-01-20 10:45:14
回答 2查看 1.1K关注 0票数 3

我最近读过很多关于对象和数组的文章,但由于某种原因,它们有相反的信息/事实。我需要你的帮助,一劳永逸地学习:什么时候最好使用数组,什么时候使用对象?

显而易见的原因是当您需要特定的顺序时使用数组。还有什么?这个例子呢?

  • 有很大的压力
  • 有很多检查数组是否包含
  • 有很多的移除

请注意,这个示例所需的数字要小得多(以千为单位)。

我为这个问题编写的代码,除了这个问题,我几乎没有做过的事情:

代码语言:javascript
运行
复制
var x = [];
var y = [];
var z = [];

var clickedX = [];
var clickedY = [];
var clickedZ = [];

var count = 100;

for ( var a = 0; a < count; a++ ) {

    //For the sake of this example: random int 1, 2 or 3
    var type = Math.floor(Math.random() * 3) + 1;

    createDiv( type );
}


function createDiv( thisType ) {

    var self = this;
    var div = self.div;

    var type = thisType;

    if( !div ) {

        div = this.div = document.createElement( 'div' );
        div.className = 'marker';

        //Push to "right" array
        if( type == '1' ) {

            x.push( self );
        }
        else if ( type == '2' ) {

            y.push( self );
        }
        else {

            z.push( self );
        }

        //Attach click event
        div.onclick = function() {

            // X
            var indexX = x.indexOf( self );

            if( indexX > -1 ) { 

                //Push to new array
                clickedX.push( self );

                //Remove from old array
                x.splice( indexX, 1 );
            }

            // Y
            var indexY = y.indexOf( self );

            if( indexY > -1 ) { 

                //Push to new array
                clickedY.push( self );

                //Remove from old array
                y.splice( indexY, 1 );
            }

            // Z
            var indexZ = z.indexOf( self );

            if( indexZ > -1 ) { 

                //Push to new array
                clickedZ.push( self );

                //Remove from old array
                z.splice( indexZ, 1 );
            }
        }; // onclick
    } // if( !div )
} // createDiv()

数据示例我目前正在处理的内容:

代码语言:javascript
运行
复制
// Data Im dealing with

objects = { 

    { objects1: [
                    0: { object : [4-5 assigned values (int, string, array)] }, 
                    1: { object : [4-5 assigned values (int, string, array)] },
                    //etc
                ] 
    }, 
    { objects2: [
                    0: {object}, 
                    1: {object},
                    //etc
                ] 
    } 
}

// 1. I need to iterate through every "object" in both "objects1" and "objects2"
// 2. I need to iterate through "array" in every "object" in "objects1"


for( /* "object" count in "objects1" */ ) {

    //Do something for each "object" in "objects1"

    for( /* items in "array" count */ ) {

        //Do something for each item in "array"
    }
}

// AND

for( /* "object" count in "objects2" */ ) {

    //Do something for each "object" in "objects2"
}
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2016-01-20 11:10:10

列阵

基本上,当您有一个后续数据列表时,您需要使用一个数组,并且您将使用它作为一个集合。

轻松地添加迭代获取计数检查是否存在

很难删除数组中的项。

此外,它还存储order

例如,如果您有10个整数,并且需要找到最小整数的索引,那么使用数组是合乎逻辑的。

对象

使用对象,当您的项目有键(特别是非整数)并且您将一个接一个地处理它们时。

方便添加删除检查是否存在属性。然而,通过对象属性迭代不太方便,获取其计数也是完全不合适的。

存储项目的order也是不可能的。

时间复杂度

回答你关于推动、检查是否存在和删除的问题:

  • 属性设置和数组推送都需要O(1)时间,但我坚信第一个时间要慢一点
  • 检查是否存在需要相同的O(1)时间
  • 移除元素是数组没有设计的地方--它需要移动所有项并花费O(n)时间,而您可以删除O(1)的属性。

不良使用实例

有一些非常糟糕的用法。如果您有以下情况,则使用数组或对象错误。

  1. 为数组分配一个随机值: 变量a= [];a1000 = 1; 它将将数组的length属性更改为1001,如果您试图输出该数组,您将得到以下内容: 未定义,未定义..。1 如果不是故意的话,那是绝对没有用的。
  2. 将相应值赋值给对象 变量a= {};for (var i= 0;i< 10;i++) { ai = 1;}

你的代码

谈到您的代码,有很多种方法可以正确地做到这一点--只需选择一个。我会这样做的:

代码语言:javascript
运行
复制
var items = [];

for (var i = 0; i < count; i++)
{
    var o = {
        type: Math.floor(Math.random() * 3) + 1,
        isClicked: false
    };

    var div = document.createElement('div');
    div.className = 'marker';

    div.onclick = function() {
        o.isClicked = true;
    };

    o.div = div;
    items.push(o);
}

function GetDivs(type, isClicked)
{
    var result = items;
    if (type) 
        result = result.filter(function(x) { return x.type === type; });
    if (isClicked !== undefined) 
        result = result.filter(function(x) { return x.isClicked === isClicked; });
    return result;
}

然后,您将能够获得任何您想要的项目:

代码语言:javascript
运行
复制
var all = GetItems(0); // or even GetDivs()
var allClicked = GetItems(0, true);
var allNotClicked = GetItems(0, false);

var divsTypeA = GetItems(1);
var clickedDivsTypeB = GetItems(2, true);
var notClickedDivsTypeC = GetItems(3, false);

通过这种用法,您根本不需要删除任何项目--只需将其标记为单击或未单击即可,这需要O(1)时间。

jQuery

如果使用jQuery和data属性,则根本不需要使用数组或对象:

代码语言:javascript
运行
复制
for (var i = 0; i < count; i++)
{
    $('<div/>')
      .addClass('marker')
      .attr('data-type', Math.floor(Math.random() * 3) + 1)
      .appendTo('body')
      .click(function() {
          $(this).addClass('clicked');
      });
}

现在,您可以使用选择器查找任何项:

代码语言:javascript
运行
复制
var all = $('.marker');
var allClicked = $('.marker.clicked');
var allNotClicked = $('.marker:not(.clicked)');

var divsTypeA = $('.marker[data-type='1']');
var clickedDivsTypeB = $('.marker[data-type='2'].clicked');
var notClickedDivsTypeC = $('.marker[data-type='1']:not(.clicked)');

但是,如果您确实有数千条记录,最后一种方法可能会产生滞后。同时,在页面上设置1000个动态div是个好主意吗?:)

票数 4
EN

Stack Overflow用户

发布于 2016-01-20 11:35:23

当其他所有的测试都失败时,同样取决于您打算使用数据结构的是什么,所有的事情都是权衡性能的,性能的\\效率的。

做好准备,等待几秒钟的测试完成。

代码语言:javascript
运行
复制
function gimmeAHugeArray( length ){
  var arr = [];
  for( var ii = 0; ii < length; ii++ ){
    arr.push( (ii * 100000 ).toString(16) );
  }
  return arr;
}

function gimmeAHugeObject( length ){
  var obj = {};
  for( var ii = 0; ii < length; ii++ ){
    obj[ (ii * 100000 ).toString(16) ] = ii;
  }
  return obj;
}

var hugeArray = gimmeAHugeArray( 100000 );
var hugeObject = gimmeAHugeObject( 100000 );
var key = (8000 * 100000).toString(16);

console.perf(function arrayGetWithIndexOf(){
  var val = hugeArray.indexOf( key );
});

console.perf(function objectGetWithKey(){
  var val = hugeObject[ key ];
});

console.perf(function arrayIterateAllProperties(){
  var val = null;
  for( var ii = 0, ll = hugeArray.length; ii < ll; ii++ ){
    val = hugeArray[ii];
  }
}, 50);

console.perf(function objectIterateAllProperties(){
  var val = null,
      key;
  for( key in hugeObject ){
    val = hugeObject[ key ];
  }
}, 50);
代码语言:javascript
运行
复制
<script src="http://codepen.io/synthet1c/pen/WrQapG.js"></script>

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/34897840

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档