简体   繁体   English

javascript数组由两个键混合

[英]javascript array mix by two keys

I have the following array of 3 (or more) different types and groups: Lets say colors and shapes, I want to spread that item as much as possible (not random)我有以下 3 个(或更多)不同类型和组的数组:让我们说颜色和形状,我想尽可能多地传播该项目(不是随机的)

['blue', 'green', 'red']
['circle', 'rect', 'tri']

they are organized in an array它们被组织在一个数组中

[
  {type: 'blue', group: 'circle'}, {type: 'blue', group: 'rect'}, {type: 'blue',group: 'tri'},
  {type: 'green', group: 'circle'}, {type: 'green', group: 'rect'},
  {type: 'red', group: 'circle'}, {type: 'red', group: 'rect'}, {type: 'red',group: 'tri'},
]

I'm trying to sort it in a way that two different groups or types won't follow each other and also the group will follow (circle,rect,tri):我正在尝试以两种不同的组或类型不会相互跟随并且该组也将跟随的方式对其进行排序(circle,rect,tri):

[
  {type: 'blue', group: 'circle'}, {type: 'green', group: 'rect'}, {type: 'red',group: 'tri'},
  {type: 'green', group: 'circle'}, {type: 'red', group: 'rect'}, {type: 'blue',group: 'tri'},
  {type: 'red', group: 'circle'}, {type: 'blue', group: 'rect'},
]

I was tying to go with several different ways, mapping the groups then types, mapping types then groups.我想用几种不同的方式,先映射组然后类型,映射类型然后组。

The idea is to be able to display it on screen (react) as there won't be two type / groups one next to the other.这个想法是能够在屏幕上显示它(反应),因为不会有两个类型/组一个挨着另一个。

Use forEach loop on array which need to be ordered ( shapes ) and calculate the index of colors .在需要排序( shapes )的数组上使用forEach循环并计算colors的索引。

 const shapes = ["circle", "rect", "tri"]; const colors = ["blue", "green", "red"]; const res = []; colors.forEach((_, ci) => { shapes.forEach((group, si) => { const type = colors[(ci + si) % colors.length]; res.push({ type, group }); }); }); console.log(res);

I have a working code, result is predictable and not random:我有一个工作代码,结果是可预测的,而不是随机的:

let types = ['blue', 'green', 'red', 'black'];
let groups = ['circle', 'rect', 'tri'];

let result = [], index1 = 0; index2 = 0;
let totalResult = types.length * groups.length;
for (let i = 0; i < totalResult; i++) {
    result.push({type: types[index1], group: groups[index2]});
    index1++;
    index2++;

    // Reset counter
    if (index1 === types.length) index1 = 0;
    if (index2 === groups.length) index2 = 0;
}

console.log(result)

And the output meet your requirement.并且输出满足您的要求。 Could you give it a try?你可以试试吗?

You could take a brute force method by generating all possible pairs and then collect the pairs by avoiding duplicates with a backtracking algorithm.您可以通过生成所有可能的对来采用蛮力方法,然后通过使用回溯算法避免重复来收集对。

 function getAllPairs(left, right) { var pairs = []; for (let i = 0; i < left.length; i++) { for (let j = 0; j < right.length; j++) { pairs.push([left[i], right[j]]); } } return pairs; } function check(array) { const sets = [new Set, new Set]; return array.every(a => a.every((v, i) => !sets[i].has(v) && sets[i].add(v))); } function fill(result, pairs) { if (!pairs.length) return result; var left = result.slice(Math.floor(result.length / half) * half); for (let i = 0; i < pairs.length; i++) { if (check([...left, pairs[i]])) { var newResult = fill([...result, pairs[i]], [...pairs.slice(0, i), ...pairs.slice(i + 1)]); if (newResult) return newResult; } } } var type = ['blue', 'green', 'red'], group = ['circle', 'rect', 'tri'], half = Math.sqrt(type.length * group.length), result = fill([], getAllPairs(type, group)) .map(([type, group]) => ({ type, group })); console.log(result);
 .as-console-wrapper { max-height: 100% !important; top: 0; }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM