0

I am trying to transform an array of objecst with keys: name and winRatio to another array of objects with a key of each unique name and value of an item in the winRatio array.

The purpose of this problem is to transform incomming data and reformat it into a chart realizing solution (Recharts, if you're interested)

Input

const data = [
  {
    name: 'Tyler',
    winRatio: [1, 0.5, 0.6666666666666666],
  },
  {
    name: 'Lizzie',
    winRatio: [0, 0.5, 0.3333333333333333],
  },
];

Output

const formatted = [
  {
    index: 0,
    Tyler: 1,
    Lizzie: 0,
  },
  {
    index: 1,
    Tyler: 0.5,
    Lizzie: 0.5,
  },
 {
    index: 2,
    Tyler: 0.6666,
    Lizzie: .333,
  },
];

I thought about using map and reduce array functions, but I can't quite seem to wrap my mind around that.

Note Additionally, each object in the output should have an index value associated with the object that increments by one.

Note The length of the outputed array should be equal to the longest length of any winRatio array. For example, if the winRatio for 'Tyler' has 20 items, the output array should have 20 objects.

2 Answers 2

1

Here's one way you could use a reducer to do it. It loops through the data array, taking each players object and combining it into the final array in the format you requested.

const reducer = (previousValue, currentValue,index) => {
    let current = {}

    currentValue.winRatio.forEach( (x, index) => {
        current = previousValue[index] ?? { index };
        current[currentValue.name] = x
        previousValue[index] = current
    })

    return previousValue
}

data.reduce(reducer, [])

As to your two notes, the output is an array so it should know its index, but you could add a line to the forEach block in this example adding an index key/value pair if one doesn't exist yet as you loop through. For your second note, I'm not sure how to figure that out without just sorting the array (or going through it and noting the longest winRatio length) first, so I guess you could just do that.

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

1 Comment

The first note was sovled like you said, by adding an index in the object. The second note was more of an edge case that would most likely solve itself
0

A fairly straightforward use of Object .fromEntries might help:

const format = (xs) => 
  Array .from ({length: Math .max (...xs .map ((x) => x .winRatio .length))}, 
    (_, i) => Object .fromEntries ([
      ['index',  i],
      ... data .filter (({winRatio}) => winRatio .length > i)
               .map (({name, winRatio}) => [name, winRatio [i]])
    ])
  )


const data = [{name: 'Tyler', winRatio: [1, 0.5, 0.6666666666666666]}, {name: 'Lizzie', winRatio: [0, 0.5, 0.3333333333333333]}];

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

We calculate the length of the longest winRatio array, create a new Array of that length, and then for each index in the new array, create an object using Object .fromEntries on an array that includes a reference to that index and the name and nth winRatio for every entry that has one at that index.

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.