创建时如何从列表中增量选择元素分配给实例

问题描述 投票:0回答:1

我会创建一个实例并分配一个编号为X的实例,X属于[红绿蓝紫]

问题:在创建新实例时从列表中增量查找一种颜色以分配给实例。

说明: 选择的颜色始终是我们之前指定的下一个颜色。例如,如果绿色是之前分配的颜色,那么蓝色将是分配给下一个实例的下一个颜色。

如果删除了一个实例,则其分配的颜色将被释放。例如[红色(已分配)绿色(释放)蓝色(分配)紫色]。但接下来选择的颜色应该还是紫色。下次创作时将选择绿色。最多有 4 个实例。如果想重新创建就需要删除一个

当有4个实例时,不能存在重复的颜色。


我寻找要分配的颜色的预想方法如下:

eg. we have this setup
const color = [R G B P]

after we load up data from db: say we already had 

instance A: color =red

instance B: color =green


When creating new instance: 

maxColor = findTheMaxColor(a arrary of instances) [loop arrary to find out the max number]
choosingColor = findChoosingColorThatIsStillAvaliable(maxColor, a arrary of instances) [increment maxColor by 1 and then check if that was used yet, otherwise increment by 1 again til it's still there]

Then we got: 
new instance C's color = color[choosingColor] 

但是,我是否可以知道是否有更好的算法或数据结构来解决此类问题?

javascript reactjs
1个回答
0
投票

您可以有一个类来维护颜色,并为每种颜色提供一个布尔值来指示其可用性。还要在颜色数组中维护一个 current 索引。

然后,当您选择颜色时,请采用当前可用索引处或之后的第一种颜色。如果没有,则再次执行相同操作,但从索引 0 开始。如果再次没有,则意味着您选择的颜色多于可用颜色。

否则返回找到的颜色,并循环将当前索引设置为它后面的颜色(无论是否可用)。

释放一种颜色只是使给定的颜色再次可用。

这是一个可能的实现:

class Colors {
    #colors;
    #available;
    #currentIndex = 0;
    
    constructor(...colors) {
        this.#colors = colors;
        this.#available = colors.map(() => true);
    }
    
    choose() {
        let i = this.#available.indexOf(true, this.#currentIndex);
        if (i == -1) i = this.#available.indexOf(true);
        if (i == -1) throw new Error("no color available");
        this.#currentIndex = (i + 1) % this.#colors.length;
        this.#available[i] = false;
        return this.#colors[i];
    }
    release(color) {
        const i = this.#colors.indexOf(color);
        if (i == -1) throw new Error("unknown color");
        if (this.#available[i]) throw new Error("this color was not chosen");
        this.#available[i] = true;
    }
}

// Demo
const colors = new Colors("Red", "Green", "Blue", "Purple");
let a = colors.choose();
console.log("chosen", a);
let b = colors.choose();
console.log("chosen", b);
let c = colors.choose();
console.log("chosen", c);
colors.release(b);
console.log("released", b);
let d = colors.choose();
console.log("chosen", d);
let e = colors.choose();
console.log("chosen", e);
colors.release(c);
console.log("released", c);
let f = colors.choose();
console.log("chosen", f);
colors.release(f);
console.log("released", f);
colors.release(d);
console.log("released", d);
let g = colors.choose();
console.log("chosen", g);

© www.soinside.com 2019 - 2024. All rights reserved.