简体   繁体   中英

How can i find next smallest Element Key by Value in Object?

I have an object like this:

times = {
   "dawn": "Mon Jul 06 2020 01:34:46 GMT+0200 (Mitteleuropäische Sommerzeit)",
   "dusk": "Mon Jul 06 2020 22:43:02 GMT+0200 (Mitteleuropäische Sommerzeit)",
   "evening": "Mon Jul 06 2020 19:06:36 GMT+0200 (Mitteleuropäische Sommerzeit)",
   "morning": "Mon Jul 06 2020 08:02:55 GMT+0200 (Mitteleuropäische Sommerzeit)"
};

I want to compare the current time with this object and want to get the key as return value, which is closest to the current time.

I try to use this function, but I never get the right key back.

function getKeyByValue(object, value) {
    return Object.keys(object).find(key => object[key] === value || object[key] < value);
}

let date = new Date();
getKeyByValue(times, date);

What do I have to change for this to work?

You need to parse the dates in your times object.

Currently, JavaScript is just seeing them as strings so you're comparing a string to a number which returns false.

Try using Date.parse(object[key]) . This returns a number.

Convert them to date objects, get the smallest delta, iterate em.

var times = {
   "dawn": "Mon Jul 06 2020 01:34:46 GMT+0200 (Mitteleuropäische Sommerzeit)",
   "dusk": "Mon Jul 06 2020 22:43:02 GMT+0200 (Mitteleuropäische Sommerzeit)",
   "evening": "Mon Jul 06 2020 19:06:36 GMT+0200 (Mitteleuropäische Sommerzeit)",
   "morning": "Mon Jul 06 2020 08:02:55 GMT+0200 (Mitteleuropäische Sommerzeit)"
};

var closestKey = null;
var closestDelta = null;

for(key in times)
{
  var delta = Math.abs(Date.now() - Date.parse(times[key]));
  
  if(delta < closestDelta || closestDelta == null)
  {
    closestKey = key;
    closestDelta = delta;
  }
}

console.log("The closest is:" + closestKey);

There are two problems here:

  1. You're comparing strings, not dates. Use Date.parse() to get a number, or new Date() to get a Date object.
  2. You're only looking for the first matching value with .find() , not the closest. You'll have to use a more custom solution to find the closest.

This will find the time before the given time which is closest:

 // Just so this example works in the future, while still // comparing against the current time: const makeTime = (h, m) => { const today = new Date(); return new Date(today.getFullYear(), today.getMonth(), today.getDate(), h, m); } const times = { "dawn": makeTime(05, 00), // 5:00am "morning": makeTime(07, 00), // 7:00am "afternoon": makeTime(12, 00), // 12:00pm "late afternoon": makeTime(17, 00), // 5:00pm "dusk": makeTime(19, 00), // 7:00pm "evening": makeTime(20, 00), // 8:00pm "night": makeTime(23, 00) // 11:00pm }; // The important part is here: const closestTime = Object.entries(times).map(([k, v]) => [ k, Date.now() - Date.parse(v) ]).reduce((pre, cur) => cur[1] < pre[1] && cur[1] > 0? cur: pre)[0]; console.log(`Right now, it is ${closestTime}.`);

Here's how it works:

// Get a list of [ key, value ] lists for every key and value in `times`.
const closestTime = Object.entries(times)

// Turn that list of [ key, value ] and turn it into a list of keys and
// the differences between compareTime and the date in the value. Values
// in the future create negative numbers, since their Unix Epoch 
// representation is larger than the compared time.
// IE: [ [ 'morning', 12300000 /* (seconds) */ ], ... ]
  .map(([k, v]) => [ k, Date.now() - Date.parse(v) ])

// Run through that list, keeping track of the current value only if it
// is smaller than the previous value and positive.
  .reduce((pre, cur) => cur[1] < pre[1] && cur[1] > 0 ? cur : pre)

// ↑ returns [ key, value ], and we just want `key`.
[0];

If you want to compare against a specific time, replace Date.now() with Date.parse() and pass in a date string, like Date.parse('Jul 07 2020 11:25:00') .

Please check it out

 times = { "dawn": "Mon Jul 06 2020 01:34:46 GMT+0200 (Mitteleuropäische Sommerzeit)", "dusk": "Mon Jul 06 2020 22:43:02 GMT+0200 (Mitteleuropäische Sommerzeit)", "evening": "Mon Jul 06 2020 19:06:36 GMT+0200 (Mitteleuropäische Sommerzeit)", "morning": "Mon Jul 06 2020 08:02:55 GMT+0200 (Mitteleuropäische Sommerzeit)" }; let obj = {} for (time in times){ Object.assign(obj, {[time]:Math.abs(new Date() - new Date(times[time]).getTime())}); } //console.log(obj) function closestDate(obj){ let closestVal = Math.min(...Object.values(obj)) for (item in obj){ if(obj[item] === closestVal){ return item; } } } console.log(closestDate(obj));

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM