Javascript 检查用户是否已分配到特定插槽
我正在处理人员配置申请。我们有一个功能,可以将员工转移到团队中。我想添加验证,以检查用户是否已经预订了该特定时段。例如,在下面的屏幕截图中,用户mate插槽重叠。他不能在同一时间内被分配到两个队 这个问题更多的是关于数据结构的。我写的代码似乎很管用,但我对它没有信心,我相信它可以做得更好。比如不运行两个循环 如果我们需要修改数据结构以获得更好的性能,这是可以的Javascript 检查用户是否已分配到特定插槽,javascript,algorithm,data-structures,Javascript,Algorithm,Data Structures,我正在处理人员配置申请。我们有一个功能,可以将员工转移到团队中。我想添加验证,以检查用户是否已经预订了该特定时段。例如,在下面的屏幕截图中,用户mate插槽重叠。他不能在同一时间内被分配到两个队 这个问题更多的是关于数据结构的。我写的代码似乎很管用,但我对它没有信心,我相信它可以做得更好。比如不运行两个循环 如果我们需要修改数据结构以获得更好的性能,这是可以的 类应用程序扩展组件{ 状态={ selectedItem:{} }; updateDate=(索引,字段,{target:{valu
类应用程序扩展组件{
状态={
selectedItem:{}
};
updateDate=(索引,字段,{target:{value}})=>{
const{selectedItem}=this.state;
const newSelectedItem={…selectedItem};
newSelectedItem[index]=newSelectedItem[index]|{
id:new Date().getTime()
};
newSelectedItem[索引][字段]=新日期(值);
这是我的国家({
selectedItem:newSelectedItem
});
此.valiateAvailability();
};
handleDropdown=(索引,{target:{value}})=>{
const{selectedItem}=this.state;
const newSelectedItem={…selectedItem};
newSelectedItem[index]=newSelectedItem[index]|{
id:new Date().getTime()
};
newSelectedItem[index][“userId”]=值;
这是我的国家({
selectedItem:newSelectedItem
});
此.valiateAvailability();
};
有效可用性=()=>{
const{selectedItem}=this.state;
常量错误={};
for(让我选择editem){
const userId=selectedItem[i].userId;
const id=selectedItem[i].id;
const from=selectedItem[i]。from;
const to=selectedItem[i]。to;
for(让z进入selectedItem){
const fromB=selectedItem[z]。from;
const toB=selectedItem[z]。to;
如果(userId==selectedItem[z].userId&&id!==selectedItem[z].id){
if(from=fromB){
错误[z]=“错误”;
}
}
}
}
console.log(“错误”,error);
};
render(){
console.log(this.state.selectedItem);
返回(
{[1,2,3]。地图((项目,索引)=>{
返回(
this.handleDropdown(索引,e)}>
选择用户
伴侣
比尔
this.updateDate(索引,“from”,e)}
/>
this.updateDate(索引“to”,e)}
/>
);
})}
);
}
}
此演示有一个类
,其中包含一些使用ES6映射存储日期范围的方法。每个指令代表一名员工的日程安排。OP未提及如何处理重叠日期,因此以下是日期范围验证规则:
- 将日期转换为毫秒进行比较(
).getTime()
- 如果开始日期大于另一个开始日期且小于其结束日期,则使用最早的开始日期,然后新的结束日期将是两个结束日期中的较大日期
- 如果输入开始日期大于输入结束日期,则将交换这些日期
- 每个范围由一个索引存储
课程表{
建造师(id){
this.id=id;
该指数=0;
this.map=新地图;
}
addSlot([startString,endString]){
this.index=this.map.size;
让startDate=新日期(startString);
让endDate=新日期(endString);
让startTime=startDate.getTime();
让endTime=endDate.getTime()
如果(开始时间>结束时间){
设temp=endDate;
endDate=开始日期;
起始日期=温度;
}
如果(this.map.size>0){
for(让这个.map的[key,value]{
让start=value[0].getTime();
让end=value[1]。getTime();
让newStart=startTime>start&&startTimestartTime&&startendTime?值[1]:endDate;
this.map.set(键[newStart,newEnd]);
}否则{
this.map.set(this.index[startDate,endDate]);
}
}
}否则{
this.map.set(this.index[startDate,endDate]);
}
}
哈斯洛特(索引){
返回此.map.has(索引);
}
getSlot(索引){
返回此.map.get(索引);
}
viewSlots(){
让列表=“”;
for(让这个.map的[key,value]{
列表+=`
${key}:[开始:${value[0]}-
结束:${value[1]}]
`;
}
退货清单;
}
removeSlot(索引){
if(this.map.has(index)){
此.map.delete(索引);
}否则{
返回索引+'不存在';
}
}
}
常数m=新附表(“配合”);
控制台日志(m.id);
m、 添加插槽(['4/19/2019','4/28/2019']);
console.log(m.hasSlot(0));
m、 添加插槽(['04/21/2019','05/12/2019']);
控制台日志(m.hasSlot(1));
console.log(m.getSlot(0));
m、 添加插槽(['08/19/2019','09/12/2019']);
控制台日志(m.hasSlot(1));
console.log(m.getSlot(1));
log(m.viewSlots())代码>如果您对更高效的数据结构感兴趣,可以尝试在此处使用二叉树。把不重叠的间隔放在树上
由于您对不重叠的间隔感兴趣,因此在它们上定义了一个自然顺序:如果a位于时间轴上B的右侧,则间隔a>间隔B
您可以逐个添加间隔,同时检查每个新间隔是否与现有间隔重叠。对于每一个新的间隔,都需要O(logn)。如果编辑了一个间隔,那么您必须删除相应的节点并添加一个新节点,当然要保留二叉树结构
然而,在实践中,你可能会有少量的间隔,而且确实如此
class App extends Component {
state = {
selectedItem: {}
};
updateDate = (index, field, { target: { value } }) => {
const { selectedItem } = this.state;
const newSelectedItem = { ...selectedItem };
newSelectedItem[index] = newSelectedItem[index] || {
id: new Date().getTime()
};
newSelectedItem[index][field] = new Date(value);
this.setState({
selectedItem: newSelectedItem
});
this.valiateAvailibility();
};
handleDropdown = (index, { target: { value } }) => {
const { selectedItem } = this.state;
const newSelectedItem = { ...selectedItem };
newSelectedItem[index] = newSelectedItem[index] || {
id: new Date().getTime()
};
newSelectedItem[index]["userId"] = value;
this.setState({
selectedItem: newSelectedItem
});
this.valiateAvailibility();
};
valiateAvailibility = () => {
const { selectedItem } = this.state;
const error = {};
for (let i in selectedItem) {
const userId = selectedItem[i].userId;
const id = selectedItem[i].id;
const from = selectedItem[i].from;
const to = selectedItem[i].to;
for (let z in selectedItem) {
const fromB = selectedItem[z].from;
const toB = selectedItem[z].to;
if (userId == selectedItem[z].userId && id !== selectedItem[z].id) {
if (from <= toB && to >= fromB) {
error[z] = "error";
}
}
}
}
console.log("error", error);
};
render() {
console.log(this.state.selectedItem);
return (
<div className="App">
{[1, 2, 3].map((item, index) => {
return (
<div>
<select onChange={e => this.handleDropdown(index, e)}>
<option>Select User</option>
<option value="12">Mate</option>
<option value="23">Bill</option>
</select>
<input
type="date"
onChange={e => this.updateDate(index, "from", e)}
/>
<input
type="date"
onChange={e => this.updateDate(index, "to", e)}
/>
</div>
);
})}
</div>
);
}
}