首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >从jQuery数组中随机选择

从jQuery数组中随机选择
EN

Stack Overflow用户
提问于 2013-05-07 20:31:21
回答 3查看 709关注 0票数 3

我有一个JSON对象数组,我想从中获得一些随机值。我自己写了一些代码,它最终起作用了,但它太难看了,甚至显示出来。

所以我才开始问这个问题。编写以下情况的好/好方法应该是什么?

我们有这样一个JSON数组:(实际上它更长,但只是几个例子)

代码语言:javascript
运行
复制
"features" : [
    {
      "attributes" : {
        "OBJECTID" : 6, 
        "Type" : "Gebied"
      }
    }, 
    {
      "attributes" : {
        "OBJECTID" : 70, 
        "Type" : "Water"
      }
    }, 
    {
      "attributes" : {
        "OBJECTID" : 80, 
        "Type" : "Water"
      }
    }, 
    {
      "attributes" : {
        "OBJECTID" : 91, 
        "Type" : "Land"
      }
    }, 
    {
      "attributes" : {
        "OBJECTID" : 66, 
        "Type" : "Gebied"
      }
    }, 
    {
      "attributes" : {
        "OBJECTID" : 78, 
        "Type" : "Land"
      }
    }
]

从该数组中,我们要创建一个新的简单数组,其中包含,例如:

  • 带有"type" = "Gebied"的2个特性
  • 1使用"Type" = "Land"的特性

实际上,要选择的特性数量(在本例中为1和2 )可能不同(一种类型最多有20个)。

最重要的是,这些特征应该是随机选择的。

我很好奇你们会采用哪种方法,希望能够创建一个真正好的代码块来完成这个任务,而不是我现在使用的几乎100条代码规则(甚至还没有完成)。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2013-05-07 21:06:31

不知道这是不是你想要的,如果不是,我就把它删除..但这就是:

代码语言:javascript
运行
复制
var gebied = 0;
var id = new Array();

for(var i = 0; i < features.length; i++)
{
  if(features[i].attributes.Type == 'Gebied')
  {
    // saves the gebied instance +1
    id[gebied] = features[i].attributes.OBJECTID;
    gebied++;
  }
}

// pick random 2 from gebied array
var id1;
var id2;
var idListLength = id.length;

id1 = id[Math.floor(Math.random() * idListLength)];

if (idListLength > 1) {
    do {
      id2 = id[Math.floor(Math.random() * idListLength)];
    } while(id1 == id2);
}

// if it's just one random pick from array
var id1 = id[Math.floor(Math.random() * id.length)];

更新

若要输入给定的数字,请确定要选择的随机ids数:

代码语言:javascript
运行
复制
function getRandomArrayElements(arr, count) {
    var randoms = [], clone = arr.slice(0);
    for (var i = 0, index; i < count; ++i) {
        index = Math.floor(Math.random() * clone.length);
        randoms.push(clone[index]);
        clone[index] = clone.pop();
    }
    return randoms;
}

function pickRandom(count)
{
  var gebied = 0;
  var id = new Array();

  for(var i = 0; i < features.length; i++)
  {
    if(features[i].attributes.Type == 'Gebied')
    {
      // saves the gebied instance +1
      id[gebied] = features[i].attributes.OBJECTID;
      gebied++;
    }
  }

  return getRandomArrayElements(id, count);
}

示例:

代码语言:javascript
运行
复制
pickRandom($('#random').val());
票数 1
EN

Stack Overflow用户

发布于 2013-05-07 20:42:55

我不会从头开始编写代码,而是使用一个可用的富库,比如下划线

代码语言:javascript
运行
复制
var gebied = _.filter(features, function(f) {
  return f.attributes.type === 'Gebied';
});

var result = [];
result.push(gebied[_.random(0, gebied,length)])

这只是一点,但如果这是你的意思,那么剩下的就是直截了当的。

票数 0
EN

Stack Overflow用户

发布于 2013-05-07 22:15:07

这里更多的是一种解决问题的功能方法,它的优点是它坚持枯燥的原则,并产生相当可读的和可重用的代码。基本上,一对过滤器完成了所有的工作:

代码语言:javascript
运行
复制
function isType(t) { // filter by Type
  return function (el) {
    return el.attributes.Type === t;
  }
}

function chooseR(r) { // filter for choosing r of length
  var found = 0;

  return function (el, idx, arr) {
    // calculate probability to keep [# needed / # left]
    var keep = Math.random() < (r - found) / (arr.length - idx);

    // increment if keeping
    keep && found++;

    return keep;
  }
}

var myGebied = features.filter(isType('Gebied')).filter(chooseR(2)),
    myLand = features.filter(isType('Land')).filter(chooseR(1));

chooseR算法只是从列表中选择任意N个元素的答案算法的一种滤波自适应算法。显然,chooseR(1)是愚蠢的,但我保留它只是为了展示这种方法的原理。

如果您不关心IE8,Array.prototype.filter是标准的ES5规范(见浏览器支持)。否则,确保在某个地方拿起一个垫片(链接到的MDN页面底部有一个)。

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

https://stackoverflow.com/questions/16428030

复制
相关文章

相似问题

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