0

I currently have an array of objects and some of them have duplicate key values, specifically the country key in this example. I'm trying to join all the objects in that array with the same country value into an array within that objects array itself.

const objects = [
  { name: 'name1', url: 'name1.com', country: 'IT' },
  { name: 'name2', url: 'name2.com', country: 'IT' },
  { name: 'name3', url: 'name3.com', country: 'IT' },
  { name: 'name4', url: 'name4.com', country: 'IT' },
  { name: 'name5', url: 'name5.com', country: 'IT' },

  { name: 'name6', url: 'name6.com', country: 'CN' },
  { name: 'name7', url: 'name7.com', country: 'CN' },
  { name: 'name8', url: 'name8.com', country: 'CN' },

  { name: 'name9', url: 'name9.com', country: 'AL' },

  { name: 'name10', url: 'name10.com', country: 'CZ' },
  { name: 'name11', url: 'name11.com', country: 'CZ' },

  { name: 'name12', url: 'name12.com', country: 'GB' },
  { name: 'name13', url: 'name13.com', country: 'GB' },
  { name: 'name14', url: 'name14.com', country: 'GB' },
  { name: 'name15', url: 'name15.com', country: 'GB' },

  { name: 'name16', url: 'name16.com', country: 'TR' },
  { name: 'name17', url: 'name17.com', country: 'MN' },
];

So ideally i want the above array of objects to look like this, where the similar are grouped into an array inside that array, including objects that don't have repeated countries, i want them in their own array too:

const newArrayofArrayofObjects = [
  [
    { name: 'name1', url: 'name1.com', country: 'IT' },
    { name: 'name2', url: 'name2.com', country: 'IT' },
    { name: 'name3', url: 'name3.com', country: 'IT' },
    { name: 'name4', url: 'name4.com', country: 'IT' },
    { name: 'name5', url: 'name5.com', country: 'IT' }
  ],
  [
    { name: 'name6', url: 'name6.com', country: 'CN' },
    { name: 'name7', url: 'name7.com', country: 'CN' },
    { name: 'name8', url: 'name8.com', country: 'CN' }
  ],
  [{ name: 'name9', url: 'name9.com', country: 'AL' }],
  [
    { name: 'name10', url: 'name10.com', country: 'CZ' },
    { name: 'name11', url: 'name11.com', country: 'CZ' }
  ],
  [
    { name: 'name12', url: 'name12.com', country: 'GB' },
    { name: 'name13', url: 'name13.com', country: 'GB' },
    { name: 'name14', url: 'name14.com', country: 'GB' },
    { name: 'name15', url: 'name15.com', country: 'GB' }
  ],
  [{ name: 'name16', url: 'name16.com', country: 'TR' }],
  [{ name: 'name17', url: 'name17.com', country: 'MN' }]
];

I tried to achieve what i want with the following code:

let newObjects= [];

Object.entries(objects).forEach(([key, value]) => {

    for (let i=0; i < objects.length; i++){
        newObjects.push([{ name: value.name, url: value.url, country: value.country}])
    }

});

Not quite achieving what i want, any help is appreciated.

2 Answers 2

3

You could group the objects with an object for same groups.

const
    objects = [{ name: 'name1', url: 'name1.com', country: 'IT' }, { name: 'name2', url: 'name2.com', country: 'IT' }, { name: 'name3', url: 'name3.com', country: 'IT' }, { name: 'name4', url: 'name4.com', country: 'IT' }, { name: 'name5', url: 'name5.com', country: 'IT' }, { name: 'name6', url: 'name6.com', country: 'CN' }, { name: 'name7', url: 'name7.com', country: 'CN' }, { name: 'name8', url: 'name8.com', country: 'CN' }, { name: 'name9', url: 'name9.com', country: 'AL' }, { name: 'name10', url: 'name10.com', country: 'CZ' }, { name: 'name11', url: 'name11.com', country: 'CZ' }, { name: 'name12', url: 'name12.com', country: 'GB' }, { name: 'name13', url: 'name13.com', country: 'GB' }, { name: 'name14', url: 'name14.com', country: 'GB' }, { name: 'name15', url: 'name15.com', country: 'GB' }, { name: 'name16', url: 'name16.com', country: 'TR' }, { name: 'name17', url: 'name17.com', country: 'MN' }],
    grouped = Object.values(objects.reduce((r, o) => {
        (r[o.country] ??= []).push(o);
        return r;
    }, {}));

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

By having sorted data by country, or at least all same countries are grouped together, you could check the predecessor and create a new group.

const
    objects = [{ name: 'name1', url: 'name1.com', country: 'IT' }, { name: 'name2', url: 'name2.com', country: 'IT' }, { name: 'name3', url: 'name3.com', country: 'IT' }, { name: 'name4', url: 'name4.com', country: 'IT' }, { name: 'name5', url: 'name5.com', country: 'IT' }, { name: 'name6', url: 'name6.com', country: 'CN' }, { name: 'name7', url: 'name7.com', country: 'CN' }, { name: 'name8', url: 'name8.com', country: 'CN' }, { name: 'name9', url: 'name9.com', country: 'AL' }, { name: 'name10', url: 'name10.com', country: 'CZ' }, { name: 'name11', url: 'name11.com', country: 'CZ' }, { name: 'name12', url: 'name12.com', country: 'GB' }, { name: 'name13', url: 'name13.com', country: 'GB' }, { name: 'name14', url: 'name14.com', country: 'GB' }, { name: 'name15', url: 'name15.com', country: 'GB' }, { name: 'name16', url: 'name16.com', country: 'TR' }, { name: 'name17', url: 'name17.com', country: 'MN' }],
    grouped = objects.reduce((r, o, i, a) => {
        if (!i || a[i -1].country !== o.country) r.push([]);
        r[r.length - 1].push(o);
        return r;
    }, []);

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

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

2 Comments

upvoted for the brilliant use of the nullish coalescing operator - where did you get the as-console-wrapper from?
just write it in the CSS section. (somebody found it out, some years ago.)
1

You could group the data by country using Map object.

const objects = [
  { name: 'name1', url: 'name1.com', country: 'IT' },
  { name: 'name2', url: 'name2.com', country: 'IT' },
  { name: 'name3', url: 'name3.com', country: 'IT' },
  { name: 'name4', url: 'name4.com', country: 'IT' },
  { name: 'name5', url: 'name5.com', country: 'IT' },

  { name: 'name6', url: 'name6.com', country: 'CN' },
  { name: 'name7', url: 'name7.com', country: 'CN' },
  { name: 'name8', url: 'name8.com', country: 'CN' },

  { name: 'name9', url: 'name9.com', country: 'AL' },

  { name: 'name10', url: 'name10.com', country: 'CZ' },
  { name: 'name11', url: 'name11.com', country: 'CZ' },

  { name: 'name12', url: 'name12.com', country: 'GB' },
  { name: 'name13', url: 'name13.com', country: 'GB' },
  { name: 'name14', url: 'name14.com', country: 'GB' },
  { name: 'name15', url: 'name15.com', country: 'GB' },

  { name: 'name16', url: 'name16.com', country: 'TR' },
  { name: 'name17', url: 'name17.com', country: 'MN' },
];
const map = new Map();
objects.forEach((x) => {
  const key = x.country;
  if (map.has(key)) map.set(key, [...map.get(key), x]);
  else map.set(key, [x]);
});
const ret = [...map.values()];
console.log(ret);

1 Comment

Thanks @mr-hr You're a star! I really need to study the Map object as a whole as i thought map was only limited to array.map(item => item)

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.