1
\$\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

1
\$\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\$ Commented Oct 5, 2021 at 14:27

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.