AndyJamesN
AndyJamesN

Reputation: 498

How to replace values in my array of objects using key from other object in another array

I have 2 arrays of objects

NOTE: status and original-language can't be set manually as they change all the time, these are custom fields. The slugs from fields make up all custom fields.

const items = [
  {
    name: 'Surviving the Game',
    status: 'ffdb29ba075fcbc0b71295c31a13d64f',
    original-language: 'b4ebbe06702794d1cf375274197267b2',
  },
  {
    name: 'Some Movie',
    status: 'cd53c082c6ca9e7d3ec66890e66c01f3',
    original-language: '7a1cac74217747933bb3915888dea090',
  },
];
const fields = [
  {
    slug: 'status',
    options: [
      {
        name: 'Released',
        id: 'ffdb29ba075fcbc0b71295c31a13d64f',
      },
      {
        name: 'Upcoming',
        id: 'cd53c082c6ca9e7d3ec66890e66c01f3',
      },
    ],
  },
  {
    slug: 'original-language',
    options: [
      {
        name: 'de',
        id: 'b4ebbe06702794d1cf375274197267b2',
      },
      {
        name: 'en',
        id: '7a1cac74217747933bb3915888dea090',
      },
    ],
  },
];

status and original-language in [items] have an id value which matches an option in the corresponding fields array.

I am trying to return a new array for [items] with the name from options with the matching id.

eg:

[
  {
    name: 'Surviving the Game',
    status: 'Released',
    original-language: 'de',
  },
  {
    name: 'Some Movie',
    status: 'Upcoming',
    original-language: 'en',
  },
];

How would I go about this with ES6/7?

I am not sure where to start

Upvotes: 0

Views: 129

Answers (3)

Nick
Nick

Reputation: 16576

I would accomplish this by creating a lookup object that houses lookups for both your statuses and languages. You can then use this lookup object when mapping through your items.

var items = [
  {
    name: 'Surviving the Game',
    status: 'ffdb29ba075fcbc0b71295c31a13d64f',
    "original-language": 'b4ebbe06702794d1cf375274197267b2'
  },
  {
    name: 'Some Movie',
    status: 'cd53c082c6ca9e7d3ec66890e66c01f3',
    "original-language": '7a1cac74217747933bb3915888dea090'
  }
];

var fields = [
  {
    slug: 'status',
    options: [
      {
        name: 'Released',
        id: 'ffdb29ba075fcbc0b71295c31a13d64f'
      },
      {
        name: 'Upcoming',
        id: 'cd53c082c6ca9e7d3ec66890e66c01f3'
      }
    ]
  },
  {
    slug: 'original-language',
    options: [
      {
        name: 'de',
        id: 'b4ebbe06702794d1cf375274197267b2'
      },
      {
        name: 'en',
        id: '7a1cac74217747933bb3915888dea090'
      }
    ]
  }
];

const lookup = {};

fields.forEach(field => {
  lookup[field.slug] = field.options.reduce((all, option) => ({
    ...all,
    [option.id]: option.name
  }), {})
});

const translatedItems = items.map(item => {
  return Object.entries(item)
    .reduce((all, [key, val]) => ({
      ...all,
      [key]: lookup[key] ? lookup[key][val] : val
    }),{});
});

console.log(translatedItems);

Upvotes: 1

ThS
ThS

Reputation: 4773

Use map to create a new array of objects having name, status and originalLanguage fields along with the find method to get the name from fields for every status identifier.

const items = [{
    name: 'Surviving the Game',
    status: 'ffdb29ba075fcbc0b71295c31a13d64f',
    originalLanguage: 'b4ebbe06702794d1cf375274197267b2',
  },
  {
    name: 'Some Movie',
    status: 'cd53c082c6ca9e7d3ec66890e66c01f3',
    originalLanguage: '7a1cac74217747933bb3915888dea090',
  },
];
const fields = [{
      slug: 'status',
      options: [{
          name: 'Released',
          id: 'ffdb29ba075fcbc0b71295c31a13d64f',
        },
        {
          name: 'Upcoming',
          id: 'cd53c082c6ca9e7d3ec66890e66c01f3',
        },
      ],
    },
    {
      slug: 'original-language',
      options: [{
          name: 'de',
          id: 'b4ebbe06702794d1cf375274197267b2',
        },
        {
          name: 'en',
          id: '7a1cac74217747933bb3915888dea090',
        },
      ],
    },
  ],
  newArr = items.map(i => ({
    name: i.name,
    status: fields.find(f => f.slug == 'status').options.find(o => o.id == i.status).name,
    originalLanguage: fields.find(f => f.slug == 'original-language').options.find(l => l.id == i.originalLanguage).name
  }));

console.log(newArr);

Upvotes: 0

Alex Broadwin
Alex Broadwin

Reputation: 1338

I'd define a function that obtains the value for a field, like so:

function valueForField(field, id) {
    const field = fields.find((itemfields) => itemfields.slug === field);
    if(!field) return null;
    const option = field.options.find(option => option.id === id);
    if(!option) return null;
    return option.name;
}

This can then be used like so:

const newItems = items.map(item => {
    const { name } = item;
    const newItem = {name};
    newItem["original-language"] = valueForField('original-language', item["original-language"]);
    newItem.status = valueForField('status', item.status);
    return newItem;
});

Upvotes: 1

Related Questions