重新排列未排序的数组,使其遵循指定的模式



给定一个名称数组,如:

let names = [Jewel, Crown, Rob, Rob, Jewel, Crown]

如何重新排列数组,使其符合以下顺序:

[Jewel, Crown, Rob, Jewel, Crown, Rob]
基本上,这个函数应该接受一个无序的名称数组,并重新排列它,以便它返回一个与上面示例中相同顺序的数组。我想在javascript中使用。filter方法,但我很难弄清楚如何实现这样的东西。任何帮助将非常感激!

我创建了这个函数。此外,它将不属于排序模式的元素添加到列表的末尾。

let names = ["Jewel", "Crown", "Rob", "Rob", "Jewel", "Crown"];
let namesWithUnknown = ["Jewel", "Crown", "Rob", "Rob", "Jewel", "Test unknown name", "Crown"];
function sortNames(unsortedNames) {
const unsortedNamesCopy = [...unsortedNames]
const res = [];
const nextNames = {"Jewel": "Crown", "Crown": "Rob", "Rob": "Jewel"};
let nextName = "Jewel";
let count = 0;
while (unsortedNamesCopy.length !== 0 && count < 3) {
count++;
if (unsortedNamesCopy.includes(nextName)) {
res.push(nextName);
unsortedNamesCopy.splice(unsortedNamesCopy.findIndex(name => name === nextName), 1);
count = 1;
}
nextName = nextNames[nextName];
}
return res.concat(unsortedNamesCopy);
}
console.log(sortNames(names));
console.log(sortNames(namesWithUnknown));

您的需求还是很不清楚。这里有一个尝试,它做了以下假设:

  • 模式是以相同的顺序重复每个名称中的一个…至少在我们用完给定名称的实例之前,然后对剩下的每个实例重复一个,以此类推。因此,['Jewel', 'Crown', 'Rob', 'Rob', 'Rob', 'Jewel', 'Rob', 'Crown', 'Jewel', 'Rob']可以变成['Rob', 'Jewel', 'Crown', 'Rob', 'Jewel', 'Crown', 'Rob', 'Jewel', 'Rob', 'Rob'],其中我们包括['Rob', 'Jewel', 'Crown']两次,然后用完'Crown's并包括['Rob', 'Jewel']一次,然后运行我们的'Jewel's,并包括(一个)剩余的'Rob'。也许你知道你的输入是平衡的,你不必担心这种情况,但它不会造成太大的伤害。
  • 初始顺序根本不重要。而不是['Jewel', 'Crown', 'Rob', 'Jewel', 'Crown', 'Rob'],这同样有效:' ['Rob', 'Crown', 'Jewel', 'Rob', 'Crown', 'Jewel']。
  • 您的值是字符串或其他可以作为对象键的东西。

实现如下:

const counts = (names) => 
Object .entries (names .reduce ((a, n) => ((a [n] = (a [n] || 0) + 1), a), {}))
const reorder = (cs, counts = cs .filter (([_, c]) => c > 0) .sort (([, a], [, b]) => b - a)) => counts .length
? [...counts .map (([n]) => n), ...reorder (counts .map (([n, c]) => [n, c - 1])) ] 
: []
const rearrange = (names) => reorder (counts (names))
console .log (rearrange (["Jewel", "Crown", "Rob", "Rob", "Jewel", "Crown"]))
console .log (rearrange (["Jewel", "Crown", "Rob", "Rob", "Rob", "Jewel", "Rob", "Crown"]))
console .log (rearrange (["John", "Larry", "Randy", "Randy", "John", "Larry"]))
.as-console-wrapper {max-height: 100% !important; top: 0}

我们有两个辅助函数。首先,count将数组转换为对数组,包含原始数组中的值和值的计数,按计数降序排序。例如:

counts (['Rob', 'Jewel', 'Crown', 'Rob', 'Jewel', 'Crown', 'Rob', 'Jewel', 'Rob', 'Rob])
//=> `[['Rob', 5], ['Jewel', 3], ['Crown', 2]]`

第二个,reorder完成实际的工作,从仍然有计数的每个元素中提取一个,将所有计数减少1,并循环,当没有更多的非空集合时停止到一个空数组。

主函数rearrange就是由这两个函数组成的。

最新更新