我需要这样的功能:
function imbricate(...arrays){}
返回一个新数组。
imbricate(["a","c","d"],["b","c"],["z","a"],["b","y","d"],["e","f","g"])
应返回:z,a,b,y,c,d,e,f,g,因为:
const r1=imbricate(["a","c","d"],["b","c"])
const r2=imbricate(r1,["z","a"])
答案 0 :(得分:1)
您可以尝试以下逻辑:
previousIndex
(解决方案中pIndex
)创建一个变量,该变量将保存先前匹配的索引的位置index
index
大于-1
,则表示数组中存在值,我们无需推送它。pIndex
为-1
且index
为-1
,则为新项目,我们可以在最后推送它。使用新职位更新pIndex
。pIndex
不是-1
,请将当前元素推到此位置并移动其余元素。
function imbricate(){
var args = arguments;
var result = [].concat(args[0]);
for(var i = 1; i< args.length; i++){
if(!Array.isArray(args[i])) continue;
var pIndex = -1;
args[i].reduceRight(function(p,c){
var index = p.indexOf(c);
if(index < 0){
if(pIndex >= 0){
p.splice(pIndex, 0, c);
index = pIndex;
}
else{
p.push(c);
index = p.length - 1;
}
}
pIndex = index;
return p;
}, result)
}
return result;
}
var r = imbricate(["a","c","d"],["b","c"],["z","a"],["b","y","d"],["e","f","g"]);
console.log(r)
&#13;
注意:考虑到评论中@ Nina指出的歧义,可以将此答案作为参考。以上答案将优先级视为先到先得顺序。因此,如果您有[a,c], [b, c], [d, c]
,则输出为[a, b, d, c]
。
答案 1 :(得分:0)
最后,
我做了一个班轮:-)来解决我的问题:
function imbricate(...arrays) {
function split(refArray, array = []) {
if (!refArray.some(v => array.indexOf(v) > -1)) return [array];
let returnArray = [];
let previousIndex = 0;
for (const v of refArray) {
if (array.indexOf(v) > -1) {
returnArray.push(array.slice(previousIndex, array.indexOf(v) + 1));
previousIndex = array.indexOf(v);
}
}
if (previousIndex != array.length - 1) returnArray.push(array.slice(previousIndex));
return returnArray;
}
function merge(refArray = [], array = []) {
let rangeMinIndex = array.findIndex(v => refArray.indexOf(v) > -1);
let rangeMaxIndex = array.slice(rangeMinIndex + 1).findIndex(v => refArray.indexOf(v) > -1);
if (rangeMinIndex == rangeMaxIndex && rangeMinIndex < 0) return [...refArray, ...array];
if (rangeMaxIndex < 0) rangeMaxIndex = array.length - 1;
if (rangeMinIndex == rangeMaxIndex && rangeMinIndex == 0) return [...refArray];
if (rangeMinIndex == rangeMaxIndex)
return [
...refArray.slice(0, refArray.indexOf(array[rangeMinIndex])),
...array.slice(0, rangeMaxIndex),
...refArray.slice(refArray.indexOf(array[rangeMinIndex]))
];
if (
array.slice(rangeMinIndex + 1).findIndex(v => refArray.indexOf(v) > -1) == -1 &&
rangeMaxIndex == array.length - 1
)
return [
...refArray.slice(0, refArray.indexOf(array[rangeMinIndex]) + 1),
...array.slice(rangeMinIndex + 1), //, rangeMaxIndex+1),
...refArray.slice(refArray.indexOf(array[rangeMinIndex]) + 1)
];
return [
...refArray.slice(0, refArray.indexOf(array[rangeMinIndex]) + 1),
...array.slice(rangeMinIndex + 1, rangeMaxIndex + 1),
...refArray.slice(refArray.indexOf(array[rangeMinIndex]) + 1)
];
}
let current;
for (const array of arrays) {
if (!current) current = [...array];
else {
for (const splitted of split(current, array)) current = merge(current, splitted);
}
}
return current;
}
第一个数组始终是引用,它将其他数组拆分为仅包含基于引用数组中包含的值的边界的块,然后根据边界定位进行合并。
无论如何,谢谢你的帮助。