不可变的 js:使功能更..功能
immutable js: make a function more.. functional
我有一个在 Immutable.js 条记录上运行的 reducer 函数,一个 Calendar
:
const Calendar = new Record({
'events': new List(), // list of Events
});
这是 Event
的列表:
const Event = new Record({
'start': null,
'end': null,
'title': null,
});
我想将来自 Javascript 个对象的新事件添加到此列表和 return 一个新的 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 提供的功能范例来完成同样的任务?
您遇到的问题是 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
}
如果您正在处理一个成员资格很重要的集合,那么您可能希望使用 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保留顺序。
我有一个在 Immutable.js 条记录上运行的 reducer 函数,一个 Calendar
:
const Calendar = new Record({
'events': new List(), // list of Events
});
这是 Event
的列表:
const Event = new Record({
'start': null,
'end': null,
'title': null,
});
我想将来自 Javascript 个对象的新事件添加到此列表和 return 一个新的 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 提供的功能范例来完成同样的任务?
您遇到的问题是 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
}
如果您正在处理一个成员资格很重要的集合,那么您可能希望使用 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保留顺序。