具有自定义要求和数据操作的数组过滤器

时间:2017-09-18 05:59:44

标签: javascript arrays node.js sails.js

const data = [{
    employee: 70,
    month: 0,
    year: 2017,
    id: 3,
    createdAt: '2017-09-15T09:42:37.000Z',
    updatedAt: '2017-09-15T09:42:37.000Z',
    organization: 41,
    version: 1
},
{
    employee: 70,
    month: 4,
    year: 2017,
    id: 4,
    createdAt: '2017-09-15T09:59:28.000Z',
    updatedAt: '2017-09-15T09:59:28.000Z',
    organization: 41,
    version: 2
},
{
    employee: 70,
    month: 4,
    year: 2017,
    id: 5,
    createdAt: '2017-09-15T10:00:35.000Z',
    updatedAt: '2017-09-15T10:00:35.000Z',
    organization: 41,
    version: 3
},
{
    employee: 70,
    month: 4,
    year: 2017,
    id: 6,
    createdAt: '2017-09-15T10:01:18.000Z',
    updatedAt: '2017-09-15T10:01:18.000Z',
    organization: 41,
    version: 4
},
{
    employee: 70,
    month: 4,
    year: 2017,
    id: 7,
    createdAt: '2017-09-15T10:07:11.000Z',
    updatedAt: '2017-09-15T10:07:11.000Z',
    organization: 41,
    version: 5
},
{
    employee: 70,
    month: 4,
    year: 2017,
    id: 8,
    createdAt: '2017-09-15T10:40:11.000Z',
    updatedAt: '2017-09-15T10:40:11.000Z',
    organization: 41,
    version: 6
},
{
    employee: 70,
    month: 4,
    year: 2017,
    id: 9,
    createdAt: '2017-09-15T10:40:58.000Z',
    updatedAt: '2017-09-15T10:40:58.000Z',
    organization: 41,
    version: 7
}, {
    employee: 70,
    month: 7,
    year: 2017,
    id: 10,
    createdAt: '2017-09-15T10:40:58.000Z',
    updatedAt: '2017-09-15T10:40:58.000Z',
    organization: 41,
    version: 6
}, {
    employee: 70,
    month: 7,
    year: 2017,
    id: 11,
    createdAt: '2017-09-15T10:40:58.000Z',
    updatedAt: '2017-09-15T10:40:58.000Z',
    organization: 41,
    version: 7
}];
const currentMonth = // 0, 11

这里我需要制作一个算法来从数组中获取细节,

我想根据所需的月份数从阵列中获取详细信息。

  1. 如果月份数与Array中的记录匹配,则返回它,如果该月有多个记录,那么它应该通过查看版本的最高值返回月份详细信息,假设在上面的数组中对于第7个月,有2个记录版本为6和7,所以我想要的是具有最高版本7的对象。

    第7个月有2条记录,所以我会得到

    { employee: 70, month: 7, year: 2017, id: 11, createdAt: '2017-09-15T10:40:58.000Z', updatedAt: '2017-09-15T10:40:58.000Z', organization: 41, version: 7 // <<==== highest version }

  2. 如果用户提供的月份数不存在,那么它应该查看靠近它的壁橱最低月份,并提供具有最高版本的对象,但是如果有更多的对象具有最低月份那么它应该采用最高版本的数据

    假设我想要第5个月或第6个月的记录,但是在数组中没有该月的记录,所以我将寻找壁橱最低月份为4,第4个月有多个记录,所以,我将过滤我想要获得具有最高版本ID的对象

    { employee: 70, month: 4, year: 2017, id: 9, createdAt: '2017-09-15T10:40:58.000Z', updatedAt: '2017-09-15T10:40:58.000Z', organization: 41, version: 7 // <<======highest version }

  3. Based on rules here,如果提供的月份数不存在且前几个月没有记录,请提供最接近所提供月份数的月份中最高版本的对象。< / p>

  4. 到目前为止我所尝试的是这里。

    这项工作看起来很简单,但我认为我让它变得更复杂.. 任何形式的帮助都非常赞赏

    const getLastEmployeeMonthVersion = data.filter(function (emp, index) {
        if (emp.month < currentMonth) {
            return _.inRange(currentMonth, data[index].month, data[data.length - 1].month) ? emp : emp
        }
    });
    
    employeeVersionForMonth = [...getLastEmployeeMonthVersion];
    const getGroupByEmployee = employeeVersionForMonth.length && _.groupBy(employeeVersionForMonth, (v) => v.employee);
    const employeeKeys = Object.keys(getGroupByEmployee);
    let latestEmployeeVersion = [];
    
    employeeKeys.forEach(emp => {
        const maxVersionId = _.maxBy(getGroupByEmployee[emp], (value) => value.version);
        latestEmployeeVersion.push(maxVersionId);
    })
    
    console.log(latestEmployeeVersion)
    

4 个答案:

答案 0 :(得分:1)

根据您的要求调用以下函数获取结果

function findMonthRecords(month, recur)
{
    var ret_records = [];

    for (i in data)
    {
        var record = data[i];

        if (record["month"] == month)
        {
            ret_records.push(record)
        }
    }   

    if (ret_records.length == 0 && recur)
    {
        for (var a = month - 1; a >= 0; a--) 
        {
            ret_records = findMonthRecords(a, false)

            if (ret_records.length > 0)
            {
                return ret_records;
            }   
        }

        for (var a = month + 1; a < 12; a++) 
        {
            ret_records = findMonthRecords(a, false)
            console.log(a);
            console.log(ret_records);
            if (ret_records.length > 0)
            {
                return ret_records;
            }   
        }   
    }   

    return ret_records;
}


console.log(findMonthRecords(2, true));

答案 1 :(得分:1)

这是实现该算法的另一种方法。

<强> 1。带filter的{​​{1}}数组会列出月份少于当月的所有记录。

<强> 2。 o.month <= currentMonth orderBy,然后是month

第3。来自version列表的head第一条记录将作为您的记录。

ordered

var result= _.head(
  _.orderBy(
    _.filter(data,
      function(o) {
        return o.month <= currentMonth;
      }), ['month', 'version'], ['desc', 'desc']));
const data = [{
  employee: 70,
  month: 0,
  year: 2017,
  id: 3,
  createdAt: '2017-09-15T09:42:37.000Z',
  updatedAt: '2017-09-15T09:42:37.000Z',
  organization: 41,
  version: 1
}, {
  employee: 70,
  month: 4,
  year: 2017,
  id: 4,
  createdAt: '2017-09-15T09:59:28.000Z',
  updatedAt: '2017-09-15T09:59:28.000Z',
  organization: 41,
  version: 2
}, {
  employee: 70,
  month: 4,
  year: 2017,
  id: 5,
  createdAt: '2017-09-15T10:00:35.000Z',
  updatedAt: '2017-09-15T10:00:35.000Z',
  organization: 41,
  version: 3
}, {
  employee: 70,
  month: 4,
  year: 2017,
  id: 6,
  createdAt: '2017-09-15T10:01:18.000Z',
  updatedAt: '2017-09-15T10:01:18.000Z',
  organization: 41,
  version: 4
}, {
  employee: 70,
  month: 4,
  year: 2017,
  id: 7,
  createdAt: '2017-09-15T10:07:11.000Z',
  updatedAt: '2017-09-15T10:07:11.000Z',
  organization: 41,
  version: 5
}, {
  employee: 70,
  month: 4,
  year: 2017,
  id: 8,
  createdAt: '2017-09-15T10:40:11.000Z',
  updatedAt: '2017-09-15T10:40:11.000Z',
  organization: 41,
  version: 6
}, {
  employee: 70,
  month: 4,
  year: 2017,
  id: 9,
  createdAt: '2017-09-15T10:40:58.000Z',
  updatedAt: '2017-09-15T10:40:58.000Z',
  organization: 41,
  version: 7
}, {
  employee: 70,
  month: 7,
  year: 2017,
  id: 10,
  createdAt: '2017-09-15T10:40:58.000Z',
  updatedAt: '2017-09-15T10:40:58.000Z',
  organization: 41,
  version: 6
}, {
  employee: 70,
  month: 8,
  year: 2017,
  id: 11,
  createdAt: '2017-09-15T10:40:58.000Z',
  updatedAt: '2017-09-15T10:40:58.000Z',
  organization: 41,
  version: 7
}];

const currentMonth = 11;

var employeeVersionForMonth = _.head(
  _.orderBy(
    _.filter(data,
      function(o) {
        return o.month <= currentMonth;
      }), ['month', 'version'], ['desc', 'desc']));


console.log(employeeVersionForMonth);

答案 2 :(得分:0)

散步:

const currentMonth = 5 // 0, 5, 10

let fMonth = -Infinity
let fVersion = -Infinity
let fIndex

for (let i = 0; i < data.length; i++) {
  let item = data[i]
  if ( (item.month > fMonth && item.month <= currentMonth) ||
       (item.month === fMonth && item.version > fVersion)
     ) {
    fMonth = item.month
    fVersion = item.version
    fIndex = i
  }
}

答案 3 :(得分:0)

你的意思是这样吗?

&#13;
&#13;
const data = [{
  employee: 70,
  month: 0,
  year: 2017,
  id: 3,
  createdAt: '2017-09-15T09:42:37.000Z',
  updatedAt: '2017-09-15T09:42:37.000Z',
  organization: 41,
  version: 1
}, {
  employee: 70,
  month: 4,
  year: 2017,
  id: 4,
  createdAt: '2017-09-15T09:59:28.000Z',
  updatedAt: '2017-09-15T09:59:28.000Z',
  organization: 41,
  version: 2
}, {
  employee: 70,
  month: 4,
  year: 2017,
  id: 5,
  createdAt: '2017-09-15T10:00:35.000Z',
  updatedAt: '2017-09-15T10:00:35.000Z',
  organization: 41,
  version: 3
}, {
  employee: 70,
  month: 4,
  year: 2017,
  id: 6,
  createdAt: '2017-09-15T10:01:18.000Z',
  updatedAt: '2017-09-15T10:01:18.000Z',
  organization: 41,
  version: 4
}, {
  employee: 70,
  month: 4,
  year: 2017,
  id: 7,
  createdAt: '2017-09-15T10:07:11.000Z',
  updatedAt: '2017-09-15T10:07:11.000Z',
  organization: 41,
  version: 5
}, {
  employee: 70,
  month: 4,
  year: 2017,
  id: 8,
  createdAt: '2017-09-15T10:40:11.000Z',
  updatedAt: '2017-09-15T10:40:11.000Z',
  organization: 41,
  version: 6
}, {
  employee: 70,
  month: 4,
  year: 2017,
  id: 9,
  createdAt: '2017-09-15T10:40:58.000Z',
  updatedAt: '2017-09-15T10:40:58.000Z',
  organization: 41,
  version: 7
}, {
  employee: 70,
  month: 7,
  year: 2017,
  id: 10,
  createdAt: '2017-09-15T10:40:58.000Z',
  updatedAt: '2017-09-15T10:40:58.000Z',
  organization: 41,
  version: 6
}, {
  employee: 70,
  month: 7,
  year: 2017,
  id: 11,
  createdAt: '2017-09-15T10:40:58.000Z',
  updatedAt: '2017-09-15T10:40:58.000Z',
  organization: 41,
  version: 7
}];

const currentMonth = 7;
const monthLookup = data.reduce((prev, record) => {
  return record.month > prev && record.month <= currentMonth ? record.month : prev;
}, 0);
const record = data.filter((record) => record.month === monthLookup).reduce((prev, current) => {
	return prev.version > current.version ? prev : current;
});

console.log(record);
&#13;
&#13;
&#13;

<强>更新 (添加3rd rule

&#13;
&#13;
const data = [{
  employee: 70,
  month: 2,
  year: 2017,
  id: 3,
  createdAt: '2017-09-15T09:42:37.000Z',
  updatedAt: '2017-09-15T09:42:37.000Z',
  organization: 41,
  version: 1
}, {
  employee: 70,
  month: 4,
  year: 2017,
  id: 4,
  createdAt: '2017-09-15T09:59:28.000Z',
  updatedAt: '2017-09-15T09:59:28.000Z',
  organization: 41,
  version: 2
}, {
  employee: 70,
  month: 4,
  year: 2017,
  id: 5,
  createdAt: '2017-09-15T10:00:35.000Z',
  updatedAt: '2017-09-15T10:00:35.000Z',
  organization: 41,
  version: 3
}, {
  employee: 70,
  month: 4,
  year: 2017,
  id: 6,
  createdAt: '2017-09-15T10:01:18.000Z',
  updatedAt: '2017-09-15T10:01:18.000Z',
  organization: 41,
  version: 4
}, {
  employee: 70,
  month: 4,
  year: 2017,
  id: 7,
  createdAt: '2017-09-15T10:07:11.000Z',
  updatedAt: '2017-09-15T10:07:11.000Z',
  organization: 41,
  version: 5
}, {
  employee: 70,
  month: 4,
  year: 2017,
  id: 8,
  createdAt: '2017-09-15T10:40:11.000Z',
  updatedAt: '2017-09-15T10:40:11.000Z',
  organization: 41,
  version: 6
}, {
  employee: 70,
  month: 4,
  year: 2017,
  id: 9,
  createdAt: '2017-09-15T10:40:58.000Z',
  updatedAt: '2017-09-15T10:40:58.000Z',
  organization: 41,
  version: 7
}, {
  employee: 70,
  month: 7,
  year: 2017,
  id: 10,
  createdAt: '2017-09-15T10:40:58.000Z',
  updatedAt: '2017-09-15T10:40:58.000Z',
  organization: 41,
  version: 6
}, {
  employee: 70,
  month: 7,
  year: 2017,
  id: 11,
  createdAt: '2017-09-15T10:40:58.000Z',
  updatedAt: '2017-09-15T10:40:58.000Z',
  organization: 41,
  version: 7
}];

function getRecord(month) {
  // Check if a record exists in the current or earlier months.
  const existsInCurrentOrEarlierMonth = data.some((record) => record.month <= month);
  const monthLookup = existsInCurrentOrEarlierMonth
    // Get the max month number if a record exists in the current or earlier months.
    ? Math.max.apply(null, data.reduce((earlierMonths, record) => {
      if (record.month <= month) {
        earlierMonths.push(record.month);
      }

      return earlierMonths;
    }, []))
    // Get the min month number if no records exist in the current or earlier months.
    : Math.min.apply(null, data.reduce((laterMonths, record) => {
      if (record.month > month) {
        laterMonths.push(record.month);
      }

      return laterMonths;
    }, []));

  // Filter the data with the month lookup and return the record with the highest version.
  return data.filter((record) => record.month === monthLookup).reduce((prev, current) => {
    return current.version > prev.version ? current : prev;
  });
}

console.log('Month 1 (should get month 2\'s record):', getRecord(1));
console.log('Month 7 (should get month 7\'s record):', getRecord(7));
console.log('Month 6 (should get month 4\'s record):', getRecord(6));
console.log('Month 8 (should get month 7\'s record):', getRecord(8));
&#13;
&#13;
&#13;