3

Please bear with me, I'm a novice javascript developer with a sorting problem that I can't wrap my head around.

I'm retrieving an array of objects (JSON response) by an api like this:

var arr = [
    {
        "year": "2011",
        "activity": "bowling"
    },
    {
        "year": "2009",
        "activity": "shopping",
    },
    {
        "year": "2011",
        "activity": "cooking"
    },
    {
        "year": "2006",
        "activity": "singing"
    }
]

I have a function that removes all of the duplicate years (as intended), but I wish to take the 'activity' value of the duplicate object and add it to the activity value of that same year is left after removing duplicates

My function that removes the duplicate year is as follows

var new_arr = new_arr.reduce((unique, o) => {
  if(!unique.some(obj => obj.year === o.year)) {
    unique.push(o);
  }
  return unique;
},[]);

which leaves me with this

var arr = [
    {
        "year": "2011",
        "activity": "bowling"
    },
    {
        "year": "2009",
        "activity": "shopping",
    },
    {
        "year": "2006",
        "activity": "singing"
    }
]

What I wish to accomplish:

var arr = [
    {
        "year": "2011",
        "activity": "bowling, cooking"
    },
    {
        "year": "2009",
        "activity": "shopping",
    },
    {
        "year": "2006",
        "activity": "singing"
    }
]

JSFiddle: https://jsfiddle.net/4s1uaex0/2/

I feel like I'm almost there, but I don't know where to start from here. Can anyone point me into the right direction with a guide or example? Help would be greatly appreciated! Thank you

4 Answers 4

1

you can simply use for loop

    var mem = {};
    for(var i = 0; i < arr.length; i++) {
        var currentItem = arr[i];
        var year = currentItem['year'];
        var activity =  currentItem['activity'];
        if(!mem.hasOwnProperty(year)) {
            mem[year] = { 'year' : year, "activity": []};
        }
        mem[year]['activity'].push(activity);
    }

    var final = Object.values(mem);
Sign up to request clarification or add additional context in comments.

Comments

0

Try reduce-ing the activity to an array in the accumulator first, then join each activity property by commas afterwards. You can achieve this with a single reduce, which is O(N), a some inside of it will make it O(N^2), which is not necessary and probably undesirable:

var arr = [
    {
        "year": "2011",
        "activity": "bowling"
    },
    {
        "year": "2009",
        "activity": "shopping",
    },
    {
        "year": "2011",
        "activity": "cooking"
    },
    {
        "year": "2006",
        "activity": "singing"
    }
];
const output = Object.values(
  arr.reduce((a, { year, activity }) => {
    if (!a[year]) a[year] = { year, activity: [] };
    a[year].activity.push(activity);
    return a;
  }, {})
);
output.forEach((item) => {
  item.activity = item.activity.join(', ');
});
console.log(output);

1 Comment

Thank you for your help, this is very clear and clean!
0

Instead of checking if the year already exists in your accumulator : Check and modify.

const arr = [{
    year: '2011',
    activity: 'bowling',
  },
  {
    year: '2009',
    activity: 'shopping',
  },
  {
    year: '2011',
    activity: 'cooking',
  },
  {
    year: '2011',
    activity: 'cooking',
  },
  {
    year: '2006',
    activity: 'singing',
  },
];

const new_arr = arr.reduce((tmp, x) => {
  // Already exist
  const exist = tmp.find(y => y.year === x.year);

  if (exist) {
    // Only add not existing activities to avoid duplicates
    if (exist.activity.indexOf(x.activity) === -1) {
      exist.activity = `${exist.activity}, ${x.activity}`;
    }

    return tmp;
  }

  tmp.push(x);

  return tmp;
}, []);

console.log(new_arr);

Comments

0

const inputArr = [
    {
        "year": "2011",
        "activity": "bowling"
    },
    {
        "year": "2009",
        "activity": "shopping",
    },
    {
        "year": "2011",
        "activity": "cooking"
    },
    {
        "year": "2006",
        "activity": "singing"
    }
];

const outputArr = inputArr.sort((objA, objB) => Number(objA.year) - Number(objB.year))
    .reduce((accu, obj) => {
        const len = accu.length;
        if(len == 0 || accu[len-1].year !== obj.year) {
            accu.push(obj);
        } else {
            accu[len-1].activity += ', ' + obj.activity;
        }
        return accu;
    }, []);

console.log(outputArr);

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.