我有一个JSON对象数组,我想从中获取几个随机值。 我自己写了一些代码,最后它起作用了,但是甚至显示它都很难看。
这就是我开始这个问题的原因。编码以下情况的好/好方法应该是什么?
我们有一个像这样的JSON数组:(它实际上更长,但只是一对例子)
"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"
"Type" = "Land"
实际上,要选择的功能数量(在此示例中为1和2)可能不同(单个类型最多20个)。
最重要的是,这些功能应该随机选择。
我很好奇你们会采取哪些方法,希望有助于创建一个真正好的代码块,而不是我现在使用的近100条代码规则(甚至没有完成)。
答案 0 :(得分:1)
不确定这是你想要的,如果没有,我会删除它..但是在这里:
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)];
<强>更新强>
要输入给定数字,确定要选择的随机ID数:
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);
}
示例:
pickRandom($('#random').val());
答案 1 :(得分:0)
我不会从头开始编码,而是使用其中一个丰富的库,例如underscore:
var gebied = _.filter(features, function(f) {
return f.attributes.type === 'Gebied';
});
var result = [];
result.push(gebied[_.random(0, gebied,length)])
这只是一点,但如果这是你的意思,那么剩下的就是直截了当。
答案 2 :(得分:0)
这是针对该问题的更多功能方法,其优点在于它坚持DRY原则并产生相当可读和可重用的代码。基本上,一对过滤器可以完成所有工作:
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
算法只是the answer to Select a random N elements from List中的算法的过滤器修改。显然,chooseR(1)
是愚蠢的,但我只是保留它以显示该方法的原理。
如果您不关心IE8,Array.prototype.filter
是标准的ES5规范(see browser support)。否则,请确保在某处拾取垫片(链接到的MDN页面底部有一个垫片)。