在javascript中从数组中选择另一个值

在javascript中从数组中选择另一个值,javascript,Javascript,给定ID数组时,JavaScript中的最佳方式是什么: var ids = ['ax6484', 'hx1789', 'qp0532']; 和当前id hx1789,以随机选择另一个不是ids数组中当前值的值?获取该值的索引,生成一个随机值,如果该随机值是索引,则根据生成的随机值减少1 var random = Math.floor(Math.random() * ids.length) var valueIndex = ids.indexOf("hx1789"); if (random

给定ID数组时,JavaScript中的最佳方式是什么:

var ids = ['ax6484', 'hx1789', 'qp0532'];

和当前id hx1789,以随机选择另一个不是ids数组中当前值的值?

获取该值的索引,生成一个随机值,如果该随机值是索引,则根据生成的随机值减少1

var random = Math.floor(Math.random() * ids.length)
var valueIndex = ids.indexOf("hx1789");

if (random === valueIndex) {
    if (random === 0) {
        random = 1;
    } else {
        random = random - 1;
    }
}

var randomValue = ids[random];
演示:

是的,测试数组长度,如果它是1-可能不想这样做!谢谢@ThomasStringer

if (ids.length > 1) { //do it! }
或者只需过滤掉该值并与之相对应:

var randomIndex = Math.floor(Math.random() * (ids.length - 1))
var random = ids.filter(function(id) {
    return id !== "hx1789";
})[randomIndex]

我可能会做以下几点:

var current = 'hx1789'; // whatever variable stores your current element

var random = Math.floor(Math.random() * ids.length);
if(random === ids.indexOf(current)) {
    random = (random + 1) % ids.length;
}

current = ids[random];
基本上,如果新选取的元素位于同一索引上,您只需从数组中选取下一个元素,或者如果超出范围,则选取第一个元素。

是您最好的朋友

_.sample(_.without(['ax6484', 'hx1789', 'qp0532'], 'hx1789'));
或使用变量

var myArray = ['ax6484', 'hx1789', 'qp0532'];
var currentId = 'hx1789';

var newRandomId = _.sample(_.without(myArray , currentId));

您可以创建一个重复的数组,然后从该数组中删除当前索引元素,并从带有已删除项的副本中选择一个随机元素:

var ids = ['ax6484', 'hx1789', 'qp0532'];
var currentIndex = ids.indexOf('hx1789');
var subA = ids.slice(0);
subA.splice(currentIndex , 1);
var randItem = subA[Math.floor((Math.random() * subA.length))];

.

如果您的值不是一个简单的字符串(如hx1789),而是来自要从中生成不同值的数组中的数组,则此操作会变得更加棘手:

let weekSegments = [["Su","Mo"],["Tu","We"],["Th","Fr","Sa"]];
如果有索引,则无论数组或对象嵌套的深度和/或包含的值的类型如何,索引都很简单:

let index = 1;
let segment = weekSegments[index];
let randomIndex;
let randomSegment;

if (weekSegments.length >= 1) {
    randomIndex = Math.floor(Math.random) * (weekSegments.length - 1);
    randomSegment = weekSegments.filter((val, i) => i !== index)[randomIndex];
}
没有索引,但是由于必须在过滤器函数中测试数组和/或对象相等性,事情变得更加复杂。在上面的例子中,它相当简单,因为它是一个只有一层深度的数组,而这个数组又只包含简单的值。首先,我们创建一个已排序段值的字符串表示形式,然后将其与每个过滤器迭代中的val字符串表示形式进行比较:

let segmentVals = segment.sort().join(',');

if (weekSegments.length > 1) {
    randomIndex = Math.floor(Math.random) * (weekSegments.length - 1);
    randomSegment = weekSegments.filter((val) => {
        return segmentVal !== val.sort().join(',');
    })[randomIndex];
}

当处理对象而不是深度嵌套和/或包含非嵌套值的数组和/或数组/对象时,它会转化为对象相等的粘性问题,这可能与此Q&A不完全相关,但您可能应该测试单个元素数组。否则你可能会遇到一些麻烦。谢谢你,我在@Justin用你的代码做了一个很好的包装函数-没问题,很乐意帮忙!多谢各位!@tymeJV好吧,我把这个投了上去!实际上,我打算为这个问题创建我自己的自答问答,因为尽管有一个很好的标题,但它并没有立即出现在谷歌上,但在创建我的问答时,它暗示这可能已经有了答案。我已经使用了过滤器路径,但是分配给一个新变量,然后使用它的长度而不是原始数组的长度-1。我想我更喜欢you's技术,因为我可以让它在没有额外变量的情况下工作,即使对于索引也是如此-只要把它放在最后一行的[]内。@ThomasString是的,关于数组是否必须足够大的好观点,我会将它添加到上面的注释中,但没有字符了!为什么要为这么简单的任务创建这么多临时数组?这只是一个如何使用下划线=@SebastianNette Ah来完成的示例!谢谢你抓住了,修好了。