我有一个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"
的2个特性"Type" = "Land"
的特性实际上,要选择的特性数量(在本例中为1和2 )可能不同(一种类型最多有20个)。
最重要的是,这些特征应该是随机选择的。
我很好奇你们会采用哪种方法,希望能够创建一个真正好的代码块来完成这个任务,而不是我现在使用的几乎100条代码规则(甚至还没有完成)。
发布于 2013-05-07 21:06:31
不知道这是不是你想要的,如果不是,我就把它删除..但这就是:
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数:
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());
发布于 2013-05-07 20:42:55
我不会从头开始编写代码,而是使用一个可用的富库,比如下划线。
var gebied = _.filter(features, function(f) {
return f.attributes.type === 'Gebied';
});
var result = [];
result.push(gebied[_.random(0, gebied,length)])
这只是一点,但如果这是你的意思,那么剩下的就是直截了当的。
发布于 2013-05-07 22:15:07
这里更多的是一种解决问题的功能方法,它的优点是它坚持枯燥的原则,并产生相当可读的和可重用的代码。基本上,一对过滤器完成了所有的工作:
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页面底部有一个)。
https://stackoverflow.com/questions/16428030
复制相似问题