0

I have an array called p which looks like:

[
  {
    "Day": "Monday",
    "data": [
      "chest",
      "triceps",
      "shoulders"
    ]
  },
  {
    "Day": "Tuesday",
    "data": [
      "back",
      "biceps"
    ]
  },
  {
    "Day": "Thursday",
    "data": [
      "legs"
    ]
  }
]

and I have another array, program which looks like: (skimmed down)

[
  {
    "target": "biceps",
    "data": [
      {
        "name": "barbell alternate biceps curl",
        "target": "biceps"
      },
      {
        "name": "barbell lying preacher curl",
        "target": "biceps"
      }
    ]
  },
  {
    "target": "triceps",
    "data": [
      {
        "name": "barbell incline reverse-grip press",
        "target": "triceps"
      },
      {
        "name": "barbell lying extension",
        "target": "triceps"
      }
    ]
  }
]

I need program to group the muscle groups that p.data has. It should look like:

[
      {
        "target": "chest tricep shoulder",
        "data": [
          {
            "name": "chest exercise",
            "target": "chest"
          },

          {
            "name": "tricep exercise",
            "target": "tricep"
          },
          {
            "name": "shoulder exercise",
            "target": "shoulder"
          },
        ]
      },

      {
        "target": "back biceps",
        "data": [
          {
            "name": "back exercise",
            "target": "back"
          },

          {
            "name": "bicep exercise",
            "target": "bicep"
          },
        ]
      },
]

I have tried this (sort based off array), but not the right attempt:

function mapOrder(array, order, property) {
  let ordered = [], unordered = [];

  // Iterate over each item in the supplied array of objects, separating ordered and unordered objects into their own arrays.
  array.forEach((item) => {
  if (order.indexOf(item[property]) === -1) {
      unordered.push(item);
  } else {
      ordered.push(item);
  }
  });

  // Sort the ordered array.
  ordered.sort((a, b) => {
  a = a[property], b = b[property];

  if (order.indexOf(a) < order.indexOf(b)) {
      return -1;
  } else {
      return 1;
  }
  });

  // Sort the unordered array.
  unordered.sort((a, b) => {
  a = a[property], b = b[property];

  if (a < b) {
      return -1;
  } else if (a > b) {
      return 1;
  } else {
      return 0;
  }
  });

  // Append the sorted, non-ordered array to the sorted, ordered array.
  ordered.push(...unordered);

  return ordered;
}
0

1 Answer 1

1

You can use the following implementation:

const programs = [
  {
    target: "biceps",
    data: [
      {
        name: "barbell alternate biceps curl",
        target: "biceps",
      },
      {
        name: "barbell lying preacher curl",
        target: "biceps",
      },
    ],
  },
  {
    target: "triceps",
    data: [
      {
        name: "barbell incline reverse-grip press",
        target: "triceps",
      },
      {
        name: "barbell lying extension",
        target: "triceps",
      },
    ],
  },
];

// creates a Map which maps
// muscle => Array of exercises
const lookupTable = programs.reduce(
  (map, { target, data }) => (map.set(target, data), map),
  new Map()
);

const p = [
  {
    Day: "Monday",
    data: ["chest", "triceps", "shoulders"],
  },
  {
    Day: "Tuesday",
    data: ["back", "biceps"],
  },
  {
    Day: "Thursday",
    data: ["legs"],
  },
];

// for each day map the respective exercises
const result = p.map((day) => ({
  // join together the muscles to a muscle group
  target: day.data.join(" "),
  // for each muscle get the respective exercises and put them in a list
  // if a muscle does not exist (as here in this limited example) set some default value (please adjust as you please)
  data: day.data.flatMap(
    (muscle) =>
      lookupTable.get(muscle) || {
        name: `Muscle ${muscle} does not exist`,
        target: muscle,
      }
  ),
}));
console.log(JSON.stringify(result, null, 4));
.as-console-wrapper { max-height: 100% !important; top: 0; }

First I create a lookup table using a Map which will allow for fast lookups in O(1) and maps a given muscle to an array of corresponding exercises as shown below.

I use reduce() for this but that's not required. You could just create the Map beforehand and manually add the arrays within a loop over the array.

Map(2) {
  'biceps' => [
    { name: 'barbell alternate biceps curl', target: 'biceps' },
    { name: 'barbell lying preacher curl', target: 'biceps' }
  ],
  'triceps' => [
    { name: 'barbell incline reverse-grip press', target: 'triceps' },
    { name: 'barbell lying extension', target: 'triceps' }
  ]
}

Then I use map() and flatMap() to create a training plan for each day containing all the exercises for all the named muscles that day. To create the string for the muscle group we can just join() the array of muscles.

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

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.