0
\$\begingroup\$

I do have my code running but again I'm wondering if there is a nicer solution since mine seems to be clumsy and I'm wondering if there is a better way like chaining (but I can't work out how to do that)

What I want to do is: for each element in data.lines replace properties "from" and "to" with an array of the "x" and "y" values given in data.points depending on the id.

Meaning: data.lines.[0]from = 1 - so look for which item in data.points has the id=1 and assign its values x and y to data.lines[0]from in an array for each prop in data.lines.

I do have an array like that:

data = [
      "points": [
        {
            "id": 1,
            "name": "Point 1",
            "x": 40,
            "y": 30
        },
        {
            "id": 2,
            "name": "Point 2",
            "x": 180,
            "y": 30
        },
        {
            "id": 3,
            "name": "Point 3",
            "x": 40,
            "y": 120,
        }
    ],
    "lines": [
        {
            "id": 1001,
            "from": 2,
            "to": 1
        },
        {
            "id": 1002,
            "from": 1,
            "to": 3
        },
    ]
]

So it should look like:

let newData = [
   {
            "id": 1001,
            "from": [180, 30],
            "to": [40, 30]
        },
        {
            "id": 1002,
            "from": [40, 30],
            "to": [40, 120]
        },
]

My solution looks like that but I think it's not good to use if 2x

  compileLines(data) {

    let result = [];

    data.lines.map(element => {
      data.points.filter(item => {
        if(item.id === element.from) {
          element.from = [item.x, item.y];
        }
        if(item.id === element.to) {
          element.to = [item.x, item.y];
          result.push(element);
        }
      })
    });

    this.newData = result;
  }
\$\endgroup\$

2 Answers 2

0
\$\begingroup\$

You're using map and filter but not their return values. They both return a modified version of the given array. No need to create a new one and push each element into it.

Furthermore i used find to get a single result. Combine this with destructuring and you've got the same results.

const data={points:[{id:1,name:"Point 1",x:40,y:30},{id:2,name:"Point 2",x:180,y:30},{id:3,name:"Point 3",x:40,y:120}],lines:[{id:1001,from:2,to:1},{id:1002,from:1,to:3}]};

const compileLines = ( data ) => {
  const { points, lines } = data;
  
  return lines.map(( line ) => {
    const p1 = points.find(({ id }) => id === line.from);
    const p2 = points.find(({ id }) => id === line.to);
    
    return {
      ...line,
      from: [p1.x, p1.y],
      to: [p2.x, p2.y],
    }
  });
}

const result = compileLines( data );

console.log( result );

\$\endgroup\$
0
\$\begingroup\$

You should make the points array into a lookup table to make it constant time (ie points.reduce((acc, {id, x, y}) => (acc[id] = [x, y], acc), {}).

\$\endgroup\$
1
  • \$\begingroup\$ Thank you for that hint! I tested it and like this approach very much \$\endgroup\$ Oct 5, 2021 at 14:27

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.