2017-05-21 70 views
0

我需要某些可能是常見問題的東西以及其他人也會從中受益的某些幫助,即修改對象中的日期並將其組合爲按時間順序排列的列表。總體目標是建立反映所有在一年即將到來的特殊日期列表:Javascript遍歷併合並對象中的日期

 
1 Jan - Sharpe's Anniversary 
2 May - Edward's Birthday 
12 Dec - Zero's Anniversary 
etc... 

我開始通過創建一個對象來表示此。然後將年份劃分出來,以便比較不會按照它們的初次出現次序排列它們,而是按年度計算。然後執行比較以按時間順序排列日期。然後用匹配的人員的身份註銷結果。

到目前爲止,我得到它的工作。但是,我不知道如何重複這一點,並使其乾燥。當然,爲週年紀念運行這個會很瑣碎,然後在沒有做出某種自定義功能的情況下生日。我所有的嘗試都沒有成功。

有沒有人有更優雅的解決方案?

很大程度上得益於這裏的社區:)

// Sample data 
 

 
var items = [{ 
 
    name: 'Edward', 
 
    anniversary: "2015-01-23", 
 
    birthday: "1988-05-02" 
 
    }, 
 
    { 
 
    name: 'Sharpe', 
 
    anniversary: "2017-01-01", 
 
    birthday: "1988-05-10" 
 
    }, 
 
    { 
 
    name: 'And', 
 
    anniversary: "2018-05-10", 
 
    birthday: "1988-06-12" 
 
    }, 
 
    { 
 
    name: 'The', 
 
    anniversary: "1988-08-11", 
 
    birthday: "1979-03-12" 
 
    }, 
 
    { 
 
    name: 'Magnetic', 
 
    anniversary: "2017-01-05", 
 
    birthday: "1956-06-21" 
 
    }, 
 
    { 
 
    name: 'Zeros', 
 
    anniversary: "1990-12-12", 
 
    birthday: "1935-07-23" 
 
    } 
 
]; 
 

 
// Slice out the year so that dates are annualized 
 

 
for (var i = 0; i < items.length; i++) { 
 
    items[i].anniversary = items[i].anniversary.slice(5, 10); 
 
}; 
 

 
// Sort dates in chronological order 
 
items.sort(function(a, b) { 
 
    return new Date(a.anniversary) - new Date(b.anniversary); 
 
}); 
 

 
// Console.log the dates with their associated name 
 

 
for (var i = 0; i < items.length; i++) { 
 
    console.log(items[i].anniversary + " " + items[i].name); 
 
}

回答

0

當你從像 「1988年8月11日」 的日期除去一年你「08-11 」。如果您隨後使用內置的日期解析器對此進行解析,那麼您將得到無效的日期,或者原始日期爲8月11日的日期爲0008年11月1日。解析器將看到一年和一個月,並在丟失的一天中使用1。

但是不要失望! ISO 8601日期格式可以按字符串排序,所以按照您的意思排序,並按字符串排序,而不是日期排序。

// Sample data 
 
var items = [{ 
 
    name: 'Edward', 
 
    anniversary: "2015-01-23", 
 
    birthday: "1988-05-02" 
 
    }, 
 
    { 
 
    name: 'Sharpe', 
 
    anniversary: "2017-01-01", 
 
    birthday: "1988-05-10" 
 
    }, 
 
    { 
 
    name: 'And', 
 
    anniversary: "2018-05-10", 
 
    birthday: "1988-06-12" 
 
    }, 
 
    { 
 
    name: 'The', 
 
    anniversary: "1988-08-11", 
 
    birthday: "1979-03-12" 
 
    }, 
 
    { 
 
    name: 'Magnetic', 
 
    anniversary: "2017-01-05", 
 
    birthday: "1956-06-21" 
 
    }, 
 
    { 
 
    name: 'Zeros', 
 
    anniversary: "1990-12-12", 
 
    birthday: "1935-07-23" 
 
    } 
 
]; 
 

 
// Get the events 
 
var specialDates = items.reduce(function(acc, item) { 
 
    acc.push([item.name, item.anniversary.substr(5), 'Anniversary'], [item.name, item.birthday.substr(5), 'Birthday']); 
 
    return acc; 
 
}, []).sort(function (a, b) { // sort on month 
 
    return a[1].localeCompare(b[1]); 
 
}).map(function(event) {  // Replace month number with short name 
 
    var months = [,'Jan','Feb','Mar','Apr','May','Jun', 
 
       'Jul','Aug','Sep','Oct','Nov','Dec']; 
 
    return [event[0], months[+event[1].split('-')[0]] + ' ' + event[1].substr(3), event[2]]; 
 
}); 
 

 
// Write result 
 
specialDates.forEach(function(event) { 
 
    console.log(event[1] + ': ' + event[0] + ' ' + event[2]); 
 
});

這可能是一個有點聰明,從原來的對象中獲取事件名稱,以便您可以根據需要添加儘可能多的事件類型,而不是讓他們硬編碼,所以對象像:

var items = [{ 
    name: 'Edward', 
    events: { 
     anniversary: "2015-01-23", 
     birthday: "1988-05-02" 
    } 
    }, 
    ... 

另外請注意,new Date("2015-01-23")將把字符串作爲UTC(區偏移量+00:00),所以對於格林威治以西的主機日期可能似乎是前一天。

+0

Rob這是一個完美的答案。我也對這個更聰明的版本感興趣。你會如何做到這一點? –

0
let goal = items 
.map(({ name, anniversary }) => ({ name, 'anniversary': anniversary.slice(5, 10) })) 
.sort(({ 'anniversary': a }, { 'anniversary': b }) => { 
    if(a > b) return 1; 
    if(a < b) return -1; 
    return 0; 
} 
.map(({ name, anniversary }) => anniversary + ' ' + name); 

goal.forEach(item => { console.log(item); });