![](/img/trans.png)
[英]Javascript - Check if two arrays are equal when arrays contain an object and an array
[英]Split randomly Array of Object in two equal arrays
我有这个对象数组;
let persons = [
{id: 1, name: "..."},
{id: 2, name: "..."},
{id: 3, name: "..."},
{id: 4, name: "..."},
{id: 5, name: "..."},
{id: 6, name: "..."},
{id: 7, name: "..."},
{id: 8, name: "..."}
]
我想将此数组拆分为两个长度相等的数组。 每次执行拆分数组的函数时,它应该在每个数组中返回一个随机数据,而不是相同的对象列表。
我尝试使用此功能
function splitArr(data, part) {
let list1 = [];
let list2 = [];
for(let i = 0; i < data.length ; i++) {
let random = Math.floor(Math.random() * data.length);
if(random % 2 === 0) {
list1.push(data[i]);
} else {
list2.push(data[i]);
}
}
return [list1, list2];
}
函数每次都返回完全相同长度的数组并不明显。 有时它返回 2 和 6 元素不相等的数组。
只需随机打乱数组,然后将数组拼接成两半。
对于改组数组,请使用此处提供的解决方案。
function shuffle(a) { var j, x, i; for (i = a.length - 1; i > 0; i--) { j = Math.floor(Math.random() * (i + 1)); x = a[i]; a[i] = a[j]; a[j] = x; } return a; }
要从中获取两个列表,请执行以下操作:
let list2 = shuffle([...data]); // spread to avoid mutating the original
let list1 = list2.splice(0, data.length >> 1);
移位运算符>>
用于获取数组长度的截断一半。
我认为在这种情况下,最快和更可靠的方法是使用本机数组方法。 我建议使用如下slice
方法:
function splitArr(data) {
const arrLength = data.length;
const firstArr = data.slice(0, arrLength/2);
const secArr = data.slice(arrLength / 2, arrLength);
return [firstArr, secArr];
}
这样你就得到了一个通用函数,它总是返回两个相同长度的数组。 您可以在边缘情况下使用Math.min()
和Math.ceil
进行试验(例如长度不均匀的数组)。
你可以做到这一点randojs.com真的很容易使用randoSequence
功能,不影响原数组。 然后,使用slice
函数拆分数组,并使用按位运算符>>
处理奇数长度的原始数组。
function shuffleAndSplit(arr){ var shuffled = randoSequence(arr); shuffled.forEach((item, i) => {shuffled[i] = item.value;}); return [shuffled.slice(0, shuffled.length >> 1), shuffled.slice(shuffled.length >> 1)]; } console.log(shuffleAndSplit(["a", "b", "c", "d", "e", "f", "g"]));
<script src="https://randojs.com/1.0.0.js"></script>
如果您使用数组映射函数,这可能会更简单,但这在 Internet Explorer 中存在一些问题。 如果你不关心 IE,下面是你如何用 map 来做到这一点:
function shuffleAndSplit(arr){ var shuffled = randoSequence(arr).map(item => item.value); return [shuffled.slice(0, shuffled.length >> 1), shuffled.slice(shuffled.length >> 1)]; } console.log(shuffleAndSplit(["a", "b", "c", "d", "e", "f", "g"]));
<script src="https://randojs.com/1.0.0.js"></script>
如果您只想将其拆分为两个单独的部分,则可以使用splice
。
它需要两个参数,如果要替换元素,则为三个,第一个是起始拼接索引。 第二个是要删除的元素数。 该函数将返回删除的元素,将数组分成两半。 并且由于 splice 函数正在从原始数组中删除元素,因此您将留下两个长度相等的数组(如果您有偶数个元素)。
至于数组的随机性,您可以在拆分之前简单地对其进行洗牌。 在这里我使用了杰夫的回答
/** * https://stackoverflow.com/a/6274381/5784924 * Shuffles array in place. ES6 version * @param {Array} a items An array containing the items. */ function shuffle(a) { for (let i = a.length - 1; i > 0; i--) { const j = Math.floor(Math.random() * (i + 1)); [a[i], a[j]] = [a[j], a[i]]; } return a; } let persons = shuffle([ {id: 1, name: "..."}, {id: 2, name: "..."}, {id: 3, name: "..."}, {id: 4, name: "..."}, {id: 5, name: "..."}, {id: 6, name: "..."}, {id: 7, name: "..."}, {id: 8, name: "..."} ]); let firstArray = persons.splice(0, persons.length / 2); console.log(firstArray.map((item) => item.id), persons.map((item) => item.id));
你的方法的问题是:
if(random % 2 === 0) {
list1.push(data[i]);
} else {
list2.push(data[i]);
}
您正在尝试插入一个随机数组,但是如果该数组的长度与另一个数组的长度相同,则您不会处理(这将很难做到,您将失去随机意图)
对于每次迭代,最好在每个数组中插入随机项。
let persons = [ {id: 1, name: "..."}, {id: 2, name: "..."}, {id: 3, name: "..."}, {id: 4, name: "..."}, {id: 5, name: "..."}, {id: 6, name: "..."}, {id: 7, name: "..."}, {id: 8, name: "..."} ] function splitArr(data, part) { let list1 = []; let list2 = []; let isPair = false; while(data.length > 0){ const randomEntry = Math.floor(Math.random() * data.length); const arrayToPush = isPair?list1:list2; arrayToPush.push(data[randomEntry]); data.splice(randomEntry, 1); isPair = !isPair; } console.log(list1.length, list2.length) return [list1, list2]; } splitArr(persons)
这对你有帮助吗?
function splitArr(data, count_decks) {
data = data.slice()
const decks = []
let i = 0
while (data.length) {
if (!Array.isArray(decks[i])) decks[i] = []
decks[i].push(data.splice(Math.random()*data.length, 1)[0])
i = (i+1) % count_decks
}
return decks
}
splitArr(persons, 2) // here 2 for 2 decks
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.