Home > Software engineering >  JS React: Two Objects, change properties if name matches
JS React: Two Objects, change properties if name matches

Time:01-24

i have a problem with Objects in JavaScript (React).

I have two different Objects, which are generated from two different XML-Files. Each Object has the same Names in it but the points and position can be different. My Goal is to add the Points from the second Object to the First if the name matches.

The Structure of the Objects is the following:

let obj = [{name: "Max", points: 2},{name:"Marc", points: 1}]
let obj2 = [{name:"Marc", points: 2},{name: "Max", points: 1}]

The Goal is to have one updated Object:

let updatedObj = [{name: "Max", points:3},{name:"Marc", points:3}]

My Code looks like this rn:

import React, {useState} from 'react'
import axios from 'axios'

const App = () => {

    const [list1,setList1] = useState()
    const [list2,setList2] = useState()

    const readFile = (file, number) => {
        const dayPath = `/files/`;

        axios.post(`http://localhost:5001/getData`, {dayPath, file})
        .then(res => {
            // File Number 1
            if(number === 1){
            let obj = res.data.vehicles[1].vehicle.map((item) => (
            {
              name: item.name,
              points: res.data.vehicles[0] - Number(item.Position)  1 // Vehicles Total - Position   1
            })
          )  
          setList(obj)
          }else {
            /* 
             * Get second Object -> Map -> Find matching Name ->
             * Keep the Name Value -> (Calculate) and Add Points ->
             * Push to State
             */
          }
          })}
    }

  return (
    <div>App</div>
  )

export default App

I've tried it with Object.entries, but only the last item was updated and the others were empty.

Thanks for your help!

CodePudding user response:

let obj = [{name: "Max", points: 2},{name:"Marc", points: 1}]
let obj2 = [{name:"Marc", points: 2},{name: "Max", points: 1}]

const updatedObj = obj.map((person)=> {
  const personRes = obj2.find((searchPerson)=> searchPerson.name === person.name)
  if(personRes){
    person.point  = personRes.point
  }
  return person 
})

CodePudding user response:

You could use this createCombinedArray function. It is a little longer than some solutions, but the function is very easy to read, flexible (even with inconsistent or incorrect inputs), and has a runtime complexity of O(n) (A.K.A. a linear runtime complexity):

let obj = [{name: "Max", points: 2},{name:"Marc", points: 1}]
let obj2 = [{name:"Marc", points: 2},{name: "Max", points: 1}]


function createCombinedArray(arr1, arr2) {

    //we'll keep track of how many points are associated with a name
    let pointTracker = {}

    //total all the points for every name in arr1
    for (let i = 0; i < arr1.length; i  ) {
        let currObj = arr1[i]

        //if this object has a 'name' property and a property 'number' that
        //is actually a number
        if (currObj.hasOwnProperty('name') && !isNaN(currObj.points)) {
            //then add it to the name's total if it exists
            if (pointTracker[currObj.name] !== undefined) {
                pointTracker[currObj.name]  =  currObj.points
            } else {
                //or if it doesn't exist, then make a new entry in your point
                //tracker system with those points
                pointTracker[currObj.name] =  currObj.points
            }
        }
    }

    //in addtion, total all the points for every name in arr2, also
    //in the pointTracker object
    for (let i = 0; i < arr2.length; i  ) {
        let currObj = arr2[i]

        //if this object has a 'name' property and a property 'number' that
        //is actually a number
        if (currObj.hasOwnProperty('name') && !isNaN(currObj.points)) {
            //then add it to the name's total if it exists
            if (pointTracker[currObj.name] !== undefined) {
                pointTracker[currObj.name]  =  currObj.points
            } else {
                //or if it doesn't exist, then make a new entry in your point
                //tracker system with those points
                pointTracker[currObj.name] =  currObj.points
            }
        }
    }

    let combinedArr = []

    //now fill in the currently-empty return array, by making and
    //pushing objects for all the names found in our pointTracker object
    for (let name in pointTracker) {
        combinedArr.push({name: name, points: pointTracker[name]})
    }

    return combinedArr
}

//here's the function in action
const newObj = createCombinedArray(obj, obj2)
console.log(newObj)

This code will print out the array

[ { name: 'Max', points: 3 }, { name: 'Marc', points: 3 } ]

Just include the function code anywhere in the same .js file in your React project, and use the function where ever you like in that file.

One possible downside to this solution is that if the objects in your original arrays contained any properties that weren't name or points, then those properties' values won't be inside of the new object.

  • Related