给定一个名称数组,如:
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
就是由这两个函数组成的。