Cooler-cpu
Cooler-cpu

Reputation: 31

How to add a new item to an object at a specific position with vanilla JS

Initially, I have such an object

There is more data in it, I missed it

"Citizens": [

            {
                "_id": "6070be28c98d5a0ea88f131c",
                "id": 1,
                "name": "Karl",
                "city_id": "1",
                "groups": []
            },
          ]

After passing through it in this cycle

                       for(let i = 0; i < objTmp[0]["Citizens"].length; i++){
                            for(let j = 0; j < citiesAll[0]["Cities"].length; j++){
                                if(objTmp[0]["Citizens"][i].id == citiesAll[0]["Cities"][j].id) {

           
                                  objTmp[0]["Citizens"][i].city = citiesAll[0]["Cities"][j];


                                }       
                            }
                        }

I add a city object from another object to it

I get such an object

"Citizens": [

        {
            "city": {
                "id": 1,
                "name": "Moscow",
                "data": "10000000"
            },
            "_id": "6070be28c98d5a0ea88f131c",
            "id": 1,
            "name": "Karl",
            "city_id": "1",
            "groups": []
        },

]

Question?

How can I add city not to the beginning, as shown here, but to the end?

Upvotes: 0

Views: 860

Answers (2)

Brandon McConnell
Brandon McConnell

Reputation: 6119

As Roshan mentioned, key orders aren't reliable in JS and really shouldn't be relied upon. If you need to maintain key order, I suggest using a map.

Here are examples of all both (including the unreliable object route):

1. As an Object

Because object keys have no inherent order, this may not look correct if you run it in your browser console and expand your object, but if you run the snippet below, you'll see the correct, expected order in your console. To ensure the desired order, use a map, explained further down in section 2.

1.1. As an Object using nested array-method loops

const objTmp = [{ Citizens: [{ _id: "6070be28c98d5a0ea88f131c", id: 1, name: "Karl", city_id: "1", groups: [] }]}];
const citiesAll = [{ Cities: [{ id: 1, name: "Moscow", data: "10000000" }]}];

objTmp[0]["Citizens"].forEach((citizen, i) => citiesAll[0]["Cities"].find(city => city.id && citizen.id && city.id === citizen.id && (objTmp[0]["Citizens"][i] = { ...citizen, city: { ...city } } )))

console.log(objTmp[0]["Citizens"][0]);

1.2. As an Object using nested for loops

const objTmp = [{ Citizens: [{ _id: "6070be28c98d5a0ea88f131c", id: 1, name: "Karl", city_id: "1", groups: [] }]}];
const citiesAll = [{ Cities: [{ id: 1, name: "Moscow", data: "10000000" }]}];

for (let i = 0; i < objTmp[0]["Citizens"].length; i++) {
    for (let j = 0; j < citiesAll[0]["Cities"].length; j++) {
        if (objTmp[0]["Citizens"][i].id && citiesAll[0]["Cities"][j].id && objTmp[0]["Citizens"][i].id === citiesAll[0]["Cities"][j].id) {
            objTmp[0]["Citizens"][i] = { ...objTmp[0]["Citizens"][i], city: { ...citiesAll[0]["Cities"][j] } };
            break;
        }
    }
}

console.log(objTmp[0]["Citizens"][0]);

1.3. As an Object using nested for..of loops

const objTmp = [{ Citizens: [{ _id: "6070be28c98d5a0ea88f131c", id: 1, name: "Karl", city_id: "1", groups: [] }]}];
const citiesAll = [{ Cities: [{ id: 1, name: "Moscow", data: "10000000" }]}];

{
    let i = 0;
    for (citizen of objTmp[0]["Citizens"]) {
        let j = 0;
        for (city of citiesAll[0]["Cities"]) {
            if (city.id && citizen.id && city.id === citizen.id) {
                objTmp[0]["Citizens"][i] = { ...citizen, city: { ...city } };
                break;
            }
            j++;
        }
        i++;
    }
}

console.log(objTmp[0]["Citizens"][0]);

2. As a Map

This one you'll need to run in your browser's console since StackOverflow's console cannot print JS Map data.

2.1. As a Map using nested array-method loops

// I am only using this replacer function to support logging the result Map data to the console properly. This function is not require for production-use.
const replacer = (a,e) => e instanceof Map?{dataType:"Map",value:Array.from(e.entries())}:e;

const objTmp = [{ Citizens: [{ _id: "6070be28c98d5a0ea88f131c", id: 1, name: "Karl", city_id: "1", groups: [] }]}];
const citiesAll = [{ Cities: [{ id: 1, name: "Moscow", data: "10000000" }]}];

objTmp[0]["Citizens"].forEach((citizen, i) => (objTmp[0]["Citizens"][i] = new Map(Object.entries(citizen)), citiesAll[0]["Cities"].find(city => city.id && objTmp[0]["Citizens"][i].get('id') && city.id === objTmp[0]["Citizens"][i].get('id') && (objTmp[0]["Citizens"][i].set('city', { ...city })))));

console.log(JSON.stringify(objTmp[0]["Citizens"][0], replacer, 2));

2.2. As a Map using nested for loops

// I am only using this replacer function to support logging the result Map data to the console properly. This function is not require for production-use.
const replacer = (a,e) => e instanceof Map?{dataType:"Map",value:Array.from(e.entries())}:e;

const objTmp = [{ Citizens: [{ _id: "6070be28c98d5a0ea88f131c", id: 1, name: "Karl", city_id: "1", groups: [] }]}];
const citiesAll = [{ Cities: [{ id: 1, name: "Moscow", data: "10000000" }]}];

for (let i = 0; i < objTmp[0]["Citizens"].length; i++) {
    objTmp[0]["Citizens"][i] = new Map(Object.entries(objTmp[0]["Citizens"][i]));
    for (let j = 0; j < citiesAll[0]["Cities"].length; j++) {
        if (citiesAll[0]["Cities"][j].id && objTmp[0]["Citizens"][i].get('id') && citiesAll[0]["Cities"][j].id === objTmp[0]["Citizens"][i].get('id')) {
            objTmp[0]["Citizens"][i].set('city', { ...citiesAll[0]["Cities"][j] });
            break;
        }
    }
}

console.log(JSON.stringify(objTmp[0]["Citizens"][0], replacer, 2));

2.3. As a Map using nested for..of loops

// I am only using this replacer function to support logging the result Map data to the console properly. This function is not require for production-use.
const replacer = (a,e) => e instanceof Map?{dataType:"Map",value:Array.from(e.entries())}:e;

const objTmp = [{ Citizens: [{ _id: "6070be28c98d5a0ea88f131c", id: 1, name: "Karl", city_id: "1", groups: [] }]}];
const citiesAll = [{ Cities: [{ id: 1, name: "Moscow", data: "10000000" }]}];

{
    let i = 0;
    for (citizen of objTmp[0]["Citizens"]) {
        objTmp[0]["Citizens"][i] = new Map(Object.entries(citizen));
        let j = 0;
        for (city of citiesAll[0]["Cities"]) {
            if (city.id && objTmp[0]["Citizens"][i].get('id') && city.id === objTmp[0]["Citizens"][i].get('id')) {
                objTmp[0]["Citizens"][i].set('city', { ...city });
                break;
            }
            j++;
        }
        i++;
    }
}

console.log(JSON.stringify(objTmp[0]["Citizens"][0], replacer, 2));

Upvotes: 1

Chris
Chris

Reputation: 7278

I have to disagree with the other answer(s) providing methods of ordering object keys.

My answer: don't do that. Attempting to order the keys of a JavaScript object is poor practice and is anti-semantic. People reading your code either will be confused or will rightly assume it's full of bugs.

I fully recognize that the keys will have a de-facto order but I'm offering the opinion that you shouldn't rely on it.

Use maps or tuples or something else built to have an ordering.

Upvotes: 0

Related Questions