如何使用函数式样式进行z顺序插入



我想做一个插入到一个数组基于插入顺序(推到结束),或在一个名为z的对象属性的基础上增加顺序(例如在2d图形中绘制顺序,无论是顺序的东西被添加或被z顺序覆盖)。

下面的代码为了做到这一点很麻烦,向后循环,找到索引1太远,跳过环插入而不改变。(从这里借来的)

似乎应该有一些比我的更简洁和功能。我是不是漏掉了一些可以简化和改进的语言部分?

编辑我一直在考虑findIndex作为方法,但我认为我需要reverseFindIndex这样的东西,在z相等的时候得到最后的插入顺序,我仍然想在我知道索引后改进非突变插入。

let children = [
{ z: 10 }, { z: 10 }, { z: 0 }, { z: 0 }, { z: -1 }, { z: -1 }
]
function insertZ(object, children) {
for (var index = children.length - 1; index >= 0; index--) { // yuck, not functional
if (object.z <= children[index].z) break;  // yuck, break
}
index++;  // yuck, went too far
return [  // yuck, ugly non-mutating insert
...children.slice(0, index),
object,
...children.slice(index)
]
}
let object = { z: 7, name: 'new guy' }   // after the 10s, before the 0s
// other test cases...
// let object = { z: 10, name: 'new guy' }  // after the 10s, before the 0s 
// let object = { z: -1, name: 'new guy' }  // after the -1s
// let object = { z: 90, name: 'new guy' }  // before everything
console.log(insertZ(object, children))

您可以使用递归找到插入点,传递索引:

function insertZ(object, children, index = 0) {
if (index >= children.length || children[index].z < object.z) {
return [
...children.slice(0, index),
object,
...children.slice(index),
];
}
return insertZ(object, children, index + 1);
}

生活的例子:

let children = [{ z: 10 }, { z: 10 }, { z: 0 }, { z: 0 }, { z: -1 }, { z: -1 }];
function insertZ(object, children, index = 0) {
if (index >= children.length || children[index].z < object.z) {
return [
...children.slice(0, index),
object,
...children.slice(index),
];
}
return insertZ(object, children, index + 1);
}
let object1 = { z: 7, name: "new guy" };    // after the 10s, before the 0s
console.log(insertZ(object1, children));
let object2 = { z: 10, name: "new guy" };   // after the 10s, before the 0s
console.log(insertZ(object2, children));
let object3 = { z: -1, name: "new guy" };   // after the -1s
console.log(insertZ(object3, children));
let object4 = { z: 90, name: "new guy" };   // before everything
console.log(insertZ(object4, children));
// Testing adding to an empty array
console.log(insertZ(object4, []));
.as-console-wrapper {
max-height: 100% !important;
}

如果需要,为了避免调用者传递无用的索引,可以通过私有内部函数来完成这项工作:

let children = [{ z: 10 }, { z: 10 }, { z: 0 }, { z: 0 }, { z: -1 }, { z: -1 }];
function insertZ(object, children) {
const worker = (object, dhildren, index = 0) => {
if (index >= children.length || children[index].z < object.z) {
return [
...children.slice(0, index),
object,
...children.slice(index),
];
}
return worker(object, children, index + 1);
};
return worker(object, children);
}
let object1 = { z: 7, name: "new guy" };    // after the 10s, before the 0s
console.log(insertZ(object1, children));
let object2 = { z: 10, name: "new guy" };   // after the 10s, before the 0s
console.log(insertZ(object2, children));
let object3 = { z: -1, name: "new guy" };   // after the -1s
console.log(insertZ(object3, children));
let object4 = { z: 90, name: "new guy" };   // before everything
console.log(insertZ(object4, children));
// Testing adding to an empty array
console.log(insertZ(object4, []));
.as-console-wrapper {
max-height: 100% !important;
}


或者,您可以对一堆临时数组使用递归:

function insertZ(object, children) {
if (children.length === 0) {
return [object];
}
const [first] = children;
if (first.z < object.z) {
return [object, ...children];
}
return [first, ...insertZ(object, children.slice(1))];
}

生活的例子:

let children = [{ z: 10 }, { z: 10 }, { z: 0 }, { z: 0 }, { z: -1 }, { z: -1 }];
function insertZ(object, children) {
if (children.length === 0) {
return [object];
}
const [first] = children;
if (first.z < object.z) {
return [object, ...children];
}
return [first, ...insertZ(object, children.slice(1))];
}
let object1 = { z: 7, name: "new guy" };    // after the 10s, before the 0s
console.log(insertZ(object1, children));
let object2 = { z: 10, name: "new guy" };   // after the 10s, before the 0s
console.log(insertZ(object2, children));
let object3 = { z: -1, name: "new guy" };   // after the -1s
console.log(insertZ(object3, children));
let object4 = { z: 90, name: "new guy" };   // before everything
console.log(insertZ(object4, children));
// Testing adding to an empty array:
console.log(insertZ(object4, []));
.as-console-wrapper {
max-height: 100% !important;
}

下面的代码段将在所有z > <target_value>之后推入一个新对象,即使已经有具有相同z的对象

let children = [
{ z: 10 }, { z: 10 }, { z: 7 }, { z: 0 }, { z: 0 }, { z: -1 }, { z: -1 }
]
let object = { z: 7, name: 'new guy' }   // after the 10s, before the 0s
children.push(object);
children.sort((a, b) => a.z > b.z ? -1 : 1);
console.log(children);

如果你想在之前插入它,你只需要将条件更改为a.z >= b.z

let children = [
{ z: 10 }, { z: 10 }, { z: 7 }, { z: 0 }, { z: 0 }, { z: -1 }, { z: -1 }
]
let object = { z: 7, name: 'new guy' }   // after the 10s, before the 0s
children.push(object);
children.sort((a, b) => a.z >= b.z ? -1 : 1);
console.log(children);

相关内容

  • 没有找到相关文章

最新更新