如何在javascript中按值搜索和返回对象(也许是lodash)

时间:2017-02-25 01:00:58

标签: reactjs lodash

我正在尝试制作一个复杂的查询。我有9周的课程。我试图根据这九周的日期触发一封电子邮件。所以课程就像......

jf892iejf929j
{name: Course Name,
 month1: date,
 month2: date,
 month3: date
}

现在,如果其中一个月的日期是,今天我想说,我想发送一封电子邮件。这就是我现在所拥有的。

const ia = _(courses)
            .map((course, id) => ({id, ...course}))
            .filter(course => course.course === 'Course Name')
            .filter(course => moment(new Date(course.month9)).isSameOrAfter(moment(new Date())))
            .map(course => {
                if (moment(new Date(course.month1)).isSame(moment(new Date()))) {  

    HERE IS WHERE I'M TRYING TO AVOID 9 IF THENS
                }
            })
            .value()

我正试着像

那样得到回报
 {courseId: courseId,
  coursetype: Course,
  month: month1 (the original key,
  date: date (original value of month1 key
}

我希望这是有道理的......有没有更简单的方法找到与日期相匹配的月份然后交回数据?

已编辑的问题

所以,我在这里找到了一位当地的导师来指导我,这就是我们所做的。

我们返回了值

,而不是在lodash查询中迭代
    const ia = _(courses)
            .map((course, id) => ({id, ...course}))
            .filter(course => course.course === 'Course Name')
            .filter(course => moment(new Date(course.month9)).tz("America/Phoenix").isSameOrAfter(moment(new Date(), 'day').tz("America/Phoenix")))
            .value()

然后,我们创建了这样的最终对象:

var finalObj = [];
for (var i = 0; i<ia.length; i++) {
    for (var key in ia[i]) {
        if (key.indexOf("month") >= 0) {
            if (moment(new Date(ia[i [key])).tz("America/Phoenix").isSame(moment(new Date('Mon Jul 10 2017 20:00:00 GMT-0700 (MST)'), 'day').tz("America/Phoenix"))) { 
                finalObj.push({
                    "courseId": ia[i].id,
                    "courseName": ia[i].course,
                    "month": key,
                    "date": ia[i][key]
                });
            }
        }
    }
}

这确实达到了我想要的效果,但我想知道ES6和Lodash是否有办法达到同样的效果。

1 个答案:

答案 0 :(得分:0)

这是一个非常有趣的问题 - 我经常看到的一些问题经常出现,但并不常见。如果您正在使用公共API,则几乎不可能在后端更改它。

从我所看到的,不,没有“正确”的方式这样做,但为了测试(并保持未来开发者的理智)我会鼓励分解更多。

例如,请在此处获取最终摘要:

   const ia = _(courses)
            .map((course, id) => ({id, ...course}))
            .filter(course => course.course === 'Course Name')
            .filter(course => moment(new Date(course.month9)).tz("America/Phoenix").isSameOrAfter(moment(new Date(), 'day').tz("America/Phoenix")))
            .value()

那太好了,看起来很光滑,因为你有一堆一个衬垫,但是稍后再访问它,呃,不是那么多。

您可以执行以下操作:

// -- BusinessRules.js --
/** 
 * Does x, y, z check
 */
export const createCourse = (course, id) => ({id, ...course});

/** 
 * Does x, y, z check
 */
export const isCourseX = course => course.course === 'Course Name';

/** 
 * Does x, y, z check
 */
function isTimezone(course, timezone) {
    return moment(new Date(course.month9))
        .tz(timezone)
        .isSameOrAfter(
            moment(new Date(), 'day').tz(timezone)
        );
}

// Use some partial magic to create expressive verbs
export const isTimeZoneArizona = _.partial(isTimezone, "America/Phoenix");
export const isTimeZoneMelbourne = _.partial(isTimezone, "Aussie/Melbourne");


// -- App.js --
const ia = _(courses)
            .map(createCourse)
            .filter(isCourseX)
            .filter(isTimeZoneArizona)
            .value();

它看起来与您的相似,但您现在可以构建一整套业务规则,尽可能复杂,而不会“混淆”主流。

它也更容易测试,因为您可以轻松地单独测试每个“规则”。

您还可以根据需要轻松添加更多规则。一旦经过测试,规则也可以与其他过滤器序列共享。

修改 作为旁注,避免链条,他们可以回来困扰你 - 而且他们要求你拉入所有的lodash来使用它们。

使用上面介绍的精确方法,您可以使用以下内容简化它:

const a = courses.map(createCourse).filter(isCourseX).filter(isTimeZoneArizone);