Home > Software design >  filter in array based on latestdate
filter in array based on latestdate

Time:09-16

Sample Data

var devs = [
    {
        name: 'ABC',
        age: 26,

        addr:{
            country:'India',
            city:'Pune',
            updated:'Mar 12 2012 10:00:00 AM'   //This is Date Proprty
        }
    },
    {
        name: 'ABD',
        age: 25,
      
        addr:{
            country:'India',
            city:'Pune',
            updated:'Mar 12 2012 12:00:00 AM'
        }
    },
    {
        name: 'ABI',
        age: 27,
      
        addr:{
            country:'UK',
            city:'London',
            updated:'Mar 13 2012 12:00:00 AM'
        }
    }
. ...Other
]


export interface IAddress{
    id?: string;
    country?:string;
    city?:string;
    updated?:Date;
}

let address:IAddress[];

Above is sample data. I need to implement similar case . My implementation is similar to

this.

let address= devs.filter(temp => temp.name.toLowerCase().indexOf(searchTerm.toLowerCase()) > -1).map(({addr}) => ({addr}));

Current Result:

searchTerm: AB Then in need to get Address whos name start with 'AB'

Result:

[
  
     addr:{
            country:'India',
            city:'Pune',
            updated:'Mar 12 2012 10:00:00 AM'
        },   ///this to be remove in the final result bacause City Pune allreay available

     addr:{
            country:'India',
            city:'Pune',
            updated:'Mar 12 2012 12:00:00 AM'
        },
    
      ddr:{
            country:'UK',
            city:'London',
          updated:'Mar 13 2012 12:00:00 AM'
        }
   
]

Expected Result: I nee to Remove the duplicate array based on city but latest updated date

i.e only city with Pune with 'updated:'Mar 12 2012 12:00:00 AM' only should be take in the final resullt..Please some one help me to sorr and filter latest record

CodePudding user response:

I have commented each step yo understand what we are doing

please look into my solution

var devs = [
    {
        name: 'ABC',
        age: 26,

        addr:{
            country:'India',
            city:'Pune',
            updated:'Mar 12 2012 10:00:00 AM'   //This is Date Proprty
        }
    },
    {
        name: 'ABD',
        age: 25,
      
        addr:{
            country:'India',
            city:'Pune',
            updated:'Mar 12 2012 12:00:00 AM'
        }
    },
    {
        name: 'ABI',
        age: 27,
      
        addr:{
            country:'UK',
            city:'London',
            updated:'Mar 13 2012 12:00:00 AM'
        }
    }
]

const result = devs
.map(i => i.addr) // show only addreses
.reduce((acc, curr) => {
const existed = acc.find(i => i.city === curr.city) // check if same item already exist
    if(!existed) {
    return [...acc, curr]; // if no exist - add current item
  } else {
    // Same item already stored
    if(new Date(existed.updated) < new Date(curr.updated)) { // need to check which item is newest
        return acc // newest already stored
    } else {
    const existedIndex = acc.findIndex(i => i.city === curr.city)
        acc.splice(existedIndex, 1, curr)// need yo replace oldest with newwest
      return acc; // return updated array
    }
  }
}, [])
console.log(result)

CodePudding user response:

You can use Array.reduce to create a map of devs, using the addr.city as the key.

We'll only replace any dev for a given city if their updated property is newer than the existing one:

var devs = [ { name: 'ABC', age: 26,  addr:{ country:'India', city:'Pune', updated:'Mar 12 2012 10:00:00 AM' } }, { name: 'ABD', age: 25,  addr:{ country:'India', city:'Pune', updated:'Mar 12 2012 12:00:00 AM' } }, { name: 'ABI', age: 27,  addr:{ country:'UK', city:'London', updated:'Mar 13 2012 12:00:00 AM' } } ]; 

// Update our map if 
// a) the entry doesn't exist or 
// b) the updated date is later than the most recent one.

const addresses = Object.values(devs.reduce((acc, cur) => {
   if (!acc[cur.addr.city] ||
       Date.parse(cur.addr.updated) < Date.parse(acc[cur.addr.city].addr.updated)) { 
       acc[cur.addr.city] = { addr: cur.addr };
   }
   return acc;
}, {}))

console.log('Addresses:', addresses)

CodePudding user response:

Array.reduce will do the trick for you.

const searchTerm = "AB";
var devs = [
  { name: 'ABC', age: 26, addr: { country: 'India', city: 'Pune', updated: 'Mar 12 2012 10:00:00' } },
  { name: 'ABD', age: 25, addr: { country: 'India', city: 'Pune', updated: 'Mar 12 2012 12:00:00' } },
  { name: 'ABI', age: 27, addr: { country: 'UK', city: 'London', updated: 'Mar 13 2012 12:00:00' } }
];
let address= devs.filter(temp => temp.name.toLowerCase().indexOf(searchTerm.toLowerCase()) > -1).reduce((acc, curr) => {
  // Check if a node exist in accumulator with same city
  const index = acc.findIndex((item) => item.addr.city === curr.addr.city);
  if(index > -1) {
    // If exist check fro the latest time
    const existingTime = new Date(acc[index].addr.updated).getTime();
    const newTime = new Date(curr.addr.updated).getTime();
    // Replace the node with latest time
    if(newTime > existingTime) {
      acc[index] = curr;
    }
  } else {
    acc.push(curr);
  }
  return acc;
}, []);
console.log(address);

  • Related