4

I'm trying to get two values (label and data) from my source data array, rename the label value and sort the label and data array in the result object.

If this is my source data...

const sourceData = [
    { _id: 'any', count: 12 },
    { _id: 'thing', count: 34 },
    { _id: 'value', count: 56 }
];

...the result should be:

{ label: ['car', 'plane', 'ship'], data: [12, 34, 56] }

So any should become car, thing should become plane and value should become ship.

But I also want to change the order of the elements in the result arrays using the label values, which should also order the data values.

Let's assume this result is expected:

{ label: ['ship', 'car', 'plane'], data: [56, 12, 34] }

With the following solution there is the need of two variables (maps and order). I thing it would be better to use only one kind of map, which should set the new label values and also the order. Maybe with an array?! Right now only the label values get ordered, but data values should be ordered in the same way...

const maps = { any: 'car', thing: 'plane', value: 'ship' }; // 1. Rename label values

const result = sourceData.reduce((a, c) => {
    a.label = a.label || [];
    a.data = a.data || [];

    a.label.push(maps[c._id]);
    a.data.push(c.count);

    return a;
}, {});

result.label.sort((a, b) => {
  const order = {'ship': 1, 'car': 2, plane: 3}; // 2. Set new order
  return order[a] - order[b];
})
5
  • 1
    "I thing it would be better…". Why? Less code is not, of itself, inherently "better". Commented Oct 29, 2019 at 20:17
  • @RobG You are right. But I need to set a variable, which should be used for new labeling and sorting. I think it is easier to set just one variable. I'm using the code multiple times. Using two variables increases maybe some configuration errors. That's why I think to use one one variable. Commented Oct 29, 2019 at 20:20
  • You might be able to run this at once with some alterations to an insertion sort to also do the mapping step before this but...why? What is the problem you're trying to solve with combining these two? I think it would ultimately make the code massively harder to read an maintain than reduce -> sort (or sort -> reduce) Commented Oct 29, 2019 at 20:20
  • @VLAZ Maybe you are right. I'll think about your idea. But still right now the data is not sorted with the label... Commented Oct 29, 2019 at 20:21
  • If the only concern is that there would be a mismatch between the two variables...why not just have one? Something like const config = { any: { value: 'car', order: 2}, thing: { value: 'plane', order: 3}, value: { value: 'ship', order: 1} } Commented Oct 29, 2019 at 20:23

2 Answers 2

1

You could move the information into a single object.

const
    data = [{ _id: 'any', count: 12 }, { _id: 'thing', count: 34 }, { _id: 'value', count: 56 }],
    target = { any: { label: 'car', index: 1 }, thing: { label: 'plane', index: 2 }, value: { label: 'ship', index: 0 } },
    result = data.reduce((r, { _id, count }) => {
        r.label[target[_id].index] = target[_id].label;
        r.data[target[_id].index] = count;
        return r;
    }, { label: [], data: [] })

console.log(result);

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

Comments

1

Instead of separating the data into label and data and then sorting them together, you can first sort the data and then transform.

const sourceData = [
    { _id: 'any', count: 12 },
    { _id: 'thing', count: 34 },
    { _id: 'value', count: 56 }
];

const maps = { any: 'car', thing: 'plane', value: 'ship' };

// Rename label values.
let result = sourceData.map(item => ({
  ...item,
  _id: maps[item._id]
}));

// Sort the data.
result.sort((a, b) => {
  const order = {'ship': 1, 'car': 2, plane: 3};
  return order[a._id] - order[b._id];
})

// Transform the result.
result = result.reduce((a, c) => {
    a.label = a.label || [];
    a.data = a.data || [];

    a.label.push(c._id);
    a.data.push(c.count);

    return a;
}, {});

console.log(result);

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.