如何根据值子字符串过滤键值对象

时间:2018-12-25 17:23:29

标签: javascript ecmascript-6 filtering

以下是我拥有的对象数组。每个日期都有多次对象。

"list": [
        {
            "dt": 1545760800,
            "dt_txt": "2018-12-25 18:00:00"
        },
        {
            "dt": 1545771600,
            "dt_txt": "2018-12-25 21:00:00"
        },
        {
            "dt": 1545782400,
            "dt_txt": "2018-12-26 00:00:00"
        },
        {
            "dt": 1545782400,
            "dt_txt": "2018-12-26 03:00:00"
        },
        {
            "dt": 1545782400,
            "dt_txt": "2018-12-26 04:00:00"
        }
       ]

如何过滤此对象数组,以使每个数据仅获得一个对象。 dt_txt

"list": [
        {
            "dt": 1545760800,
            "dt_txt": "2018-12-25 18:00:00"
        },
        {
            "dt": 1545782400,
            "dt_txt": "2018-12-26 00:00:00"
        }
       ]

如何获得?

2 个答案:

答案 0 :(得分:1)

您可以通过多种方式使用reduce

1]在accumulator数组中检查是否存在与dt_txt具有相同日期的对象。如果是,请跳过该项目,否则将其添加到accumulator

const list = [{"dt": 1545760800,"dt_txt": "2018-12-25 18:00:00"},{"dt": 1545771600,"dt_txt": "2018-12-25 21:00:00"},{"dt": 1545782400,"dt_txt": "2018-12-26 00:00:00"},{"dt": 1545782400,"dt_txt": "2018-12-26 03:00:00"},{"dt": 1545782400,"dt_txt": "2018-12-26 04:00:00"}]

const filter1 = list.reduce((acc, i) => (
  acc.find(a => new Date(a.dt_txt).toDateString() === new Date(i.dt_txt).toDateString())
  ? '' 
  : acc.push(i), acc), 
[]);

console.log(filter1);

2]在第二种方法中,创建了一个单独的函数compareDates来比较日期并返回boolean。我正在使用toDateString()比较日期

const list = [{"dt": 1545760800,"dt_txt": "2018-12-25 18:00:00"},{"dt": 1545771600,"dt_txt": "2018-12-25 21:00:00"},{"dt": 1545782400,"dt_txt": "2018-12-26 00:00:00"},{"dt": 1545782400,"dt_txt": "2018-12-26 03:00:00"},{"dt": 1545782400,"dt_txt": "2018-12-26 04:00:00"}]

// create a seperate function to compare the dates a return a boolean
const compareDates = (d1, d2) => new Date(d1).toDateString() === new Date(d2).toDateString();

const filter2 = list.reduce((acc, i) => (
  acc.find(a => compareDates(a.dt_txt, i.dt_txt)) ? '' : acc.push(i), acc)
,[])

console.log(filter2);

3]在第三种方法中,目标是创建一个具有唯一日期值作为键的对象。对于原始数组中的每个项目,请检查该日期是否已经作为accumulator中的键存在。如果是,请跳过上下文中的当前项目,否则添加当前项目作为其值。最后,在原始数组中有一对不同对象的键/值对。因此,只需使用Object.values

获取值

const list =[{"dt": 1545760800,"dt_txt": "2018-12-25 18:00:00"},{"dt": 1545771600,"dt_txt": "2018-12-25 21:00:00"},{"dt": 1545782400,"dt_txt": "2018-12-26 00:00:00"},{"dt": 1545782400,"dt_txt": "2018-12-26 03:00:00"},{"dt": 1545782400,"dt_txt": "2018-12-26 04:00:00"}];

// gets only the date part in string 
const getDateString = (date) => new Date(date).toDateString();

const filter3 = Object.values(
      list.reduce((acc, i) => 
        (acc[getDateString(i.dt_txt)] = acc[getDateString(i.dt_txt)] || i, acc),{}))
        
console.log(filter3);

答案 1 :(得分:1)

您要问的是,每个data.dt_txt都需要一个项目,但是您想要的结果似乎只需要data.dt_txt的第一部分。应该清楚的是,无论哪种方式都可以工作-如果您想要整个东西,那就不要分割值。

您只可以保留set可见值并根据该值进行过滤。如果找到新值,则将其添加到集合中:

let list = [{"dt": 1545760800,"dt_txt": "2018-12-25 18:00:00"},{"dt": 1545771600,"dt_txt": "2018-12-25 21:00:00"},{"dt": 1545782400,"dt_txt": "2018-12-26 00:00:00"},{"dt": 1545782400,"dt_txt": "2018-12-26 03:00:00"},{"dt": 1545782400,"dt_txt": "2018-12-26 04:00:00"}]

let seen = new Set()
let filtered = list.filter(item => {
    let [date, _] = item.dt_txt.split(' ')
    return seen.has(date) ?  false : seen.add(date)
})

console.log(filtered)