Найти максимальную дату из массива объектов и обновить, добавив флаг в Javascript - PullRequest
0 голосов
/ 22 мая 2018

Под ним находится массив объектов, содержащий два свойства emp_name и date , и я хочу обновить записи, добавив флаг, в котором date должно быть наибольшим среди других дата соответствует emp_name .

let arr_of_obj = [{emp_name:'Mark',date:new Date('2018/05/01')},
                  {emp_name:'Mark',date:new Date('2018/05/02')},
                  {emp_name:'John',date:new Date('2018/04/05')},
                  {emp_name:'John',date:new Date('2018/03/22')},
                  {emp_name:'Mark',date:new Date('2018/05/06')}];

Предположим, что выше arr_of_obj следует обновить две записи, т.е.

[{emp_name:'Mark',date:new Date('2018/05/21')},
{emp_name:'Mark',date:new Date('2018/05/22')},
{emp_name:'John',date:new Date('2018/04/15'),max:true},
{emp_name:'John',date:new Date('2018/03/22')},
{emp_name:'Mark',date:new Date('2018/05/26'),max:true}]

Ответы [ 4 ]

0 голосов
/ 22 мая 2018

let arr_of_obj = [{
    emp_name: 'Mark',
    date: new Date('2018/05/01')
  },
  {
    emp_name: 'Mark',
    date: new Date('2018/05/02')
  },
  {
    emp_name: 'John',
    date: new Date('2018/04/05')
  },
  {
    emp_name: 'John',
    date: new Date('2018/03/22')
  },
  {
    emp_name: 'Mark',
    date: new Date('2018/05/06')
  }
];

console.log('initial array', arr_of_obj);

const max_items = arr_of_obj.map((o, i) => {
  return {
    ord: i,
    emp_name: o.emp_name,
    date: o.date
  };
}).sort((a, b) => b.date - a.date).reduce((l, r) => {
  if (!Array.isArray(l)) {
    if (l.emp_name === r.emp_name) return l.date > r.date ? [l] : [r];
    return [l, r];
  }
  const last = l.slice(-1)[0];
  if (last.emp_name === r.emp_name) {
    if (last.date < r.date) l[l.length - 1] = r;
  } else l.push(r);
  return l;
});

max_items.forEach(o => arr_of_obj[o.ord] = {
  emp_name: o.emp_name,
  date: o.date,
  max: true
});

console.log('max items', max_items);
console.log('updated array', arr_of_obj);

Создает второй массив, который содержит только элементы max, вместе с их исходным индексом массива.

[ 
  { ord: 4, emp_name: 'Mark', date: 2018-05-06T07:00:00.000Z },
  { ord: 2, emp_name: 'John', date: 2018-04-05T07:00:00.000Z } 
]

Наконец, выполните итерацию по нему и обновите массивиндексы в исходном массиве.Это сохраняет порядок оригинала.Я бы также рекомендовал разбить функцию Reduction на отдельную функцию для удобства чтения, но она работает для этого примера.

0 голосов
/ 22 мая 2018

Вы можете отсортировать базу массива по дате, а затем отметить макс.смотри мой код

       let arr_of_obj = [{emp_name:'Mark',date:new Date('2018/05/01')},
                      {emp_name:'Mark',date:new Date('2018/05/02')},
                      {emp_name:'John',date:new Date('2018/04/05')},
                      {emp_name:'John',date:new Date('2018/03/22')},
                      {emp_name:'Mark',date:new Date('2018/05/06')}];

 let arr = arr_of_obj.slice().sort((a,b) => new Date(b.date) - new Date(a.date));

 let mark = arr[arr.findIndex(p => p.emp_name === 'Mark')];
 let john = arr[arr.findIndex(p => p.emp_name === 'John')];

 let new_array = arr_of_obj.map(obj => obj.date === mark.date || obj.date === john.date ? {...obj, max: true} : obj);
0 голосов
/ 22 мая 2018

Не приносит намного больше, чем @Engineer, но я стараюсь не объявлять const, а затем присваивать ему свойства, даже если это не имеет большого значения.Так что мне нравится использовать уменьшение здесь:

const max_dates = arr_of_obj.reduce((stored, item) => {
    if(!stored[item.emp_name] || stored[item.emp_name].date < item.date)
        stored[item.emp_name] = item;
    return stored;
}, {});


Object.values(max_dates).map(item => item.max = true)
0 голосов
/ 22 мая 2018
const arr = [{emp_name:'Mark',date:new Date('2018/05/01')},
              {emp_name:'Mark',date:new Date('2018/05/02')},
              {emp_name:'John',date:new Date('2018/04/05')},
              {emp_name:'John',date:new Date('2018/03/22')},
              {emp_name:'Mark',date:new Date('2018/05/06')}]

const max_map = {};   // Holds map of (name => obj_with_max_date) items, 
arr.forEach((item, i)=> {
    // Checking whether emp_name is not stored in map, then store the object 
    // and if `emp_name` is already exists in map, comparing `date` fields
    if (!max_map[item.emp_name] || max_map[item.emp_name].date < arr[i].date) {  
       max_map[item.emp_name] = arr[i];
    }
});

// Traversing the map and assigning flags for each emp_name
Object.keys(max_map).forEach( name => {
   max_map[name].max = true;
});

ДЕМО

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...