0

I'm trying to delete duplicate elements from a dictionary when the key values "hour_from" and "hour_to" are the same. I'm using a double for (I don't remember other less cost algorithms to do it) but I'm having problems with index values.

var hours_array = [
{day: "Mon", hour_from: "00:00", hour_to: "00:00"},
{day: "Mon", hour_from: "00:00", hour_to: "00:16"},
{day: "Mon", hour_from: "00:00", hour_to: "00:16"},
{day: "Thu", hour_from: "00:00", hour_to: "00:25"},
{day: "Mon", hour_from: "00:00", hour_to: "00:33"},
{day: "Fri", hour_from: "00:00", hour_to: "00:83"},
{day: "Sat", hour_from: "02:00", hour_to: "05:33"},
{day: "Thu", hour_from: "02:00", hour_to: "05:33"},
{day: "Wed", hour_from: "12:00", hour_to: "14:00"},
{day: "Sun", hour_from: "22:25", hour_to: "13:45"}]

for (let i=0; i< hours_array.length; i++){
 for (let j=0; j<=hours_array.length; j++){
  if ((hours_array[i]['hour_from'] == hours_array[j]['hour_from']) && (hours_array[i]['hour_to'] == hours_array[j]['hour_to'])){
  delete hours_array[j];
  }
 }
}

I thought it is an error with index values:

enter image description here

Edit: Needed result:

var hours_array = [
{day: "Mon", hour_from: "00:00", hour_to: "00:00"},
{day: "Mon", hour_from: "00:00", hour_to: "00:16"},
{day: "Thu", hour_from: "00:00", hour_to: "00:25"},
{day: "Mon", hour_from: "00:00", hour_to: "00:33"},
{day: "Fri", hour_from: "00:00", hour_to: "00:83"},
{day: "Sat", hour_from: "02:00", hour_to: "05:33"},
{day: "Wed", hour_from: "12:00", hour_to: "14:00"},
{day: "Sun", hour_from: "22:25", hour_to: "13:45"}]

Any suggestion? Any some more efficient algorithm? Thanks for reading!

8
  • 2
    Use let j=i+1 so that you don't start from the front of the array each time when searching for a value equivalent to hours_array[i] (which would always find itself) Commented Jan 23, 2020 at 15:03
  • do you want only compare hours or day as well? Commented Jan 23, 2020 at 15:04
  • I only need to compare hour_from and hour_to values for the dict @NinaScholz Commented Jan 23, 2020 at 15:05
  • Triend and the same error appears. @Bergi Commented Jan 23, 2020 at 15:05
  • 1
    please add the wanted result. Commented Jan 23, 2020 at 15:08

4 Answers 4

2

You could filter the array with the help of a Set.

If a hash value (build from hour_from and hour_to) is in the set, the item is filtered out. If not, then the hash is taken to the set and the item is used.

var getKey = ({ hour_from, hour_to }) => [hour_from, hour_to].join('|'),
    hours_array = [{ day: "Mon", hour_from: "00:00", hour_to: "00:00" }, { day: "Mon", hour_from: "00:00", hour_to: "00:16" }, { day: "Mon", hour_from: "00:00", hour_to: "00:16" }, { day: "Thu", hour_from: "00:00", hour_to: "00:25" }, { day: "Mon", hour_from: "00:00", hour_to: "00:33" }, { day: "Fri", hour_from: "00:00", hour_to: "00:83" }, { day: "Sat", hour_from: "02:00", hour_to: "05:33" }, { day: "Thu", hour_from: "02:00", hour_to: "05:33" }, { day: "Wed", hour_from: "12:00", hour_to: "14:00" }, { day: "Sun", hour_from: "22:25", hour_to: "13:45" }],
    unique = hours_array.filter((s => o => !s.has(getKey(o)) && s.add(getKey(o)))(new Set));

console.log(unique);
.as-console-wrapper { max-height: 100% !important; top: 0; }

Sign up to request clarification or add additional context in comments.

1 Comment

I liked the concept, so kept my upvote, However, as I started thinking of it in details, there seems to be no performance gain whatsoever.
1

You may go lazy way with Array.prototype.reduce() along with Array.prototype.find().

const src = [{day:"Mon",hour_from:"00:00",hour_to:"00:00"},{day:"Mon",hour_from:"00:00",hour_to:"00:16"},{day:"Mon",hour_from:"00:00",hour_to:"00:16"},{day:"Thu",hour_from:"00:00",hour_to:"00:25"},{day:"Mon",hour_from:"00:00",hour_to:"00:33"},{day:"Fri",hour_from:"00:00",hour_to:"00:83"},{day:"Sat",hour_from:"02:00",hour_to:"05:33"},{day:"Thu",hour_from:"02:00",hour_to:"05:33"},{day:"Wed",hour_from:"12:00",hour_to:"14:00"},{day:"Sun",hour_from:"22:25",hour_to:"13:45"}],
      dedupe = src.reduce((res, item) => 
        (
          !res.find(({hour_from, hour_to}) => 
            hour_from == item.hour_from && hour_to == item.hour_to) ? 
          res.push(item) : 
          true, res
        ), [])
      
console.log(dedupe)

Comments

0

In this line for (let j=0; j<=hours_array.length; j++){ you can run out of the array's boundries. In your situation the array.length is 10, however when you try to access the element with index 10 you get undefined, because your last index is 9. You either have to change <= to < or reduce the length by 1. See solution below:

for (let i=0; i< hours_array.length; i++){
  for (let j=0; j<hours_array.length; j++){
    if ((hours_array[i]['hour_from'] == hours_array[j]['hour_from']) && (hours_array[i] 
    ['hour_to'] == hours_array[j]['hour_to'])){
      delete hours_array[j];
    }
  }
}

Edit: Ok you understand this issue, the next problem is that you delete an element if the array while you are still looping. There are many ways to fix this, but the easiest one is to create a new array and push the unique elements to that new array. Let me know if you need help with that.

3 Comments

This is only part of the problem
The error still there with this code. Thanks for it. @Teodor Narliyski
@adriano009 okay see my edit please. if you would like to do it on your own, give it a go, if not let me know and I will fix the code for you (you shouldn't delete items while you loop) - keep in mind you also need to fix what I originally wrote above
0

Use reduce method with combining Object.values.

var hours_array = [
  { day: "Mon", hour_from: "00:00", hour_to: "00:00" },
  { day: "Mon", hour_from: "00:00", hour_to: "00:16" },
  { day: "Mon", hour_from: "00:00", hour_to: "00:16" },
  { day: "Thu", hour_from: "00:00", hour_to: "00:25" },
  { day: "Mon", hour_from: "00:00", hour_to: "00:33" },
  { day: "Fri", hour_from: "00:00", hour_to: "00:83" },
  { day: "Sat", hour_from: "02:00", hour_to: "05:33" },
  { day: "Thu", hour_from: "02:00", hour_to: "05:33" },
  { day: "Wed", hour_from: "12:00", hour_to: "14:00" },
  { day: "Sun", hour_from: "22:25", hour_to: "13:45" }
];

const updated = Object.values(
  hours_array.reduce(
    (acc, curr) => ({
      ...acc,
      [`${curr.hour_from}-${curr.hour_to}`]: { ...curr }
    }),
    {}
  )
);

console.log(updated);

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.