Javascript 按阵列排序,保留阵列中未找到的元素的顺序

Javascript 按阵列排序,保留阵列中未找到的元素的顺序,javascript,arrays,algorithm,sorting,Javascript,Arrays,Algorithm,Sorting,如何按模式对数组进行排序,使模式中不存在的元素不会移动到数组的末尾,但保留它们的顺序 有一个例子: let input = ['Apple', 'Banana', 'Cherry', 'Grape', 'Mango', 'Orange', 'Peach'] let pattern = ['Orange', 'Peach', 'Banana', 'Grape'] // desired output let output = ['Apple', 'Orange', 'Peach', 'Banana

如何按模式对数组进行排序,使模式中不存在的元素不会移动到数组的末尾,但保留它们的顺序

有一个例子:

let input = ['Apple', 'Banana', 'Cherry', 'Grape', 'Mango', 'Orange', 'Peach']
let pattern = ['Orange', 'Peach', 'Banana', 'Grape']

// desired output
let output = ['Apple', 'Orange', 'Peach', 'Banana', 'Cherry', 'Grape', 'Mango']
模式的长度可以等于、小于或大于输入数组的长度

标准分类:

input.sort( (a, b) => {
    let indexA = pattern.indexOf(a);
    let indexB = pattern.indexOf(b);
    return Math.sign(indexA - indexB);
});

// result:
// Apple,Cherry,Mango,Orange,Peach,Banana,Grape
// elements that are not present in pattern have been moved to the left
但是,我们希望保留阵列中不存在的元素的相对位置。实现这一目标最有效的方法是什么


使用示例:对表列重新排序(有些列可能是隐藏的,但我们记得它们的顺序)。

您可以将一个对象作为索引,获取数组中所需模式的所有索引,对其进行排序,映射原始数组,并获取模式中的项目,即已排序的项目

var输入=[“苹果”、“香蕉”、“樱桃”、“葡萄”、“芒果”、“橙子”、“桃子”],
图案=[“橙色”、“桃”、“香蕉”、“葡萄”],
patternO=Object.assign(…pattern.map((k,v)=>({[k]:v})),
索引=[…input.keys()]
.filter(i=>patternO中的输入[i]
.sort((a,b)=>patternO[input[a]]-patternO[input[b]]),
结果=input.map((j=>(v,i)=>模式中的v?输入[索引[j++]]:v)(0));
控制台日志(结果)

.as console wrapper{max height:100%!important;top:0;}
您可以循环
输入
数组,并且在
模式
数组中存在的元素的每一次出现时,递增一个计数器变量并使用该索引获取元素

let-input=[“苹果”、“香蕉”、“樱桃”、“葡萄”、“芒果”、“橘子”、“桃子”]
let pattern=[‘橙色’、‘桃子’、‘香蕉’、‘葡萄’];
设电流=0;
input.forEach((e,i)=>{
if(pattern.includes(e))输入[i]=模式[current++]
})

console.log(输入)
patternElementIndexTable
仅用于加速某些操作,可以将其删除,并在相关位置执行
indexOf
。这将降低算法的顺序,并在输入大于数千项时产生问题

首先,只考虑<代码>模式中出现的<代码>输入< /代码>元素,并创建该列表与“代码>输入< /代码>:< /P>之间的索引映射”

input.map((_, i) => i).filter(i => input[i] in patternElementIndexTable)
然后,我将赋值映射到
intermediate
的任何整数索引,以根据映射更改
input
的相关属性。这基本上意味着在
中间操作
就像在
输入
上操作一样,但只考虑所需的元素

因此,对中介进行排序会产生预期的效果:

let input=[“苹果”、“香蕉”、“樱桃”、“葡萄”、“芒果”、“橘子”、“桃子”];
let pattern=[‘橙色’、‘桃子’、‘香蕉’、‘葡萄’];
设patternElementIndexTable=pattern.reduce((p,c,i)=>(p[c]=i,p),{});
让中介=新代理(
Object.seal(input.map((u,i)=>i.filter(i=>patternElementIndexTable中的输入[i]),
{
获取:(目标、道具)=>{
如果(数字isInteger(+prop)&&+prop>=0){
如果(+prop>=目标长度)
返回未定义;
返回输入[target[prop]];
}
返回目标[道具];
},
设定:(目标、道具、价值)=>{
如果(数字isInteger(+prop)&&+prop>=0){
如果(+prop>=目标长度){
返回false;
}
输入[target[prop]]=值;
返回true;
}
返回false;
}
}
);
sort((a,b)=>patternElementIndexTable[a]-patternElementIndexTable[b]);

控制台日志(输入)输出中不保留
樱桃
的位置。为什么?你的分类规范感觉不是很严格。我想这就是为什么你不能实施它。您如何确定
Chery
Grape
之前?首先写下你的分类规则。然后,当您确切知道要做什么时,它可能更容易实现。结果不应该是
[“苹果”、“橘子”、“樱桃”、“桃子”、“芒果”、“香蕉”、“葡萄”]
?只有在
输入
模式
数组中有相同的项要替换时,这才有效。也许总是这样…@Nina Scholz是的,在这种情况下,他可以先过滤模式数组,删除输入中不存在的元素。只需
pattern=pattern.filter(e=>input.includes(pattern))
before。假设只包含一个模式项,但它不适用于多个模式项(如果需要,blablabla;-)。