我有一个适用于Immutable.js条记录的减速机功能,Calendar
:
const Calendar = new Record({
'events': new List(), // list of Events
});
这是Event
s:
const Event = new Record({
'start': null,
'end': null,
'title': null,
});
我想将Javascript对象中的新事件添加到此列表并返回新的Calendar
记录,但前提是这些对象不在列表中:
(state = new Calendar)=> {
const receivedEvent = new Event({
start: <a date>,
end: <another date>,
title: <a string>,
});
let newState;
if (state.get('events').contains(receivedEvent)){
newState = state;
} else {
newState = state
.updateIn(['events'], (events)=> events.push(receivedEvent));
}
return newState;
}
这是我现在凌晨4点才能做的最好的事情,但这似乎是一种糟糕的做法。
有没有办法更好地利用Immutable提供的功能范例来完成同样的任务?
答案 0 :(得分:2)
如果您正在处理会员资格很重要的集合,那么您可能希望使用Set而不是列表。
集合只是一组唯一值。
const Calendar = new Record({
'events': new Set(), // set of Events
});
然后,您可以将事件添加到集合中,而不必担心会出现重复值。数据结构的实现使您无需检查它是否已包含该值。
(state = new Calendar) =>
state.updateIn(['events'], calendar => calendar.add(new Event({
start: <a date>,
end: <another date>,
title: <a string>,
}));
当您表示日历时,添加事件的顺序可能并不重要,因为您可以使用事件日期本身作为列表进行排序,否则,您可以使用OrderedSet来保留日历排序
答案 1 :(得分:1)
您遇到的问题是List.contains
会使用Event
将每个receivedEvent
与===
进行比较。
即使receivedEvent
可能与您状态中已存储的属性共享相同的属性,但它们不是相同的对象。
示例:
const x = { a: 1, b: 2 };
const y = { a: 1, b: 2 };
const z = x;
x === y; // -> false
x === x; // -> true
x === z; // -> true
因此,您需要将receivedEvent
的每个属性与您要比较的每个实例进行比较。谢天谢地,有handy Immutable.is
method,您可以这样使用:
if (state.get('events').some(event => Immutable.is(receivedEvent, event))) {
// already exists in events
} else {
// doesn't already exist in events
}