I've got an object and i want to iterate through all of its subobjects/keys that hold the key-value pair 'pool: "luxury"'. Or in other words I want to iterate throu all rooms that are in the pool luxury to set a new parameter. What is a proper and efficient way to do that in js?
var rooms = {
SU01: {
enabled: true,
pool: "comfort",
ics_lnk : "https://avlblty.com/su01.ics",
ics_txt : "",
},
SU02: {
enabled: true,
pool: "luxury",
ics_lnk : "https://avlblty.com/su02.ics",
ics_txt : "",
},
SU03: {
enabled: true,
pool: "luxury",
ics_lnk : "https://avlblty.com/su03.ics",
ics_txt : "",
},
SU11: {
enabled: true,
pool: "comfort",
ics_lnk : "https://avlblty.com/su11.ics",
ics_txt : "",
},
SU12: {
enabled: true,
pool: "luxury",
ics_lnk : "https://avlblty.com/su12.ics",
ics_txt : "",
},
...
You can use Object.values()
to get all the values in the object and filter
to only keep the ones you want.
The code might look like this:
foreach (let room of Object.values(rooms).filter(r => r.pool == 'luxury')) {
// Do something with room
}
Assuming this is your data set
const data = var rooms = {
SU01: {
enabled: true,
pool: "comfort",
ics_lnk : "https://avlblty.com/su01.ics",
ics_txt : "",
},
SU02: {
enabled: true,
pool: "luxury",
ics_lnk : "https://avlblty.com/su02.ics",
ics_txt : "",
},
SU03: {
enabled: true,
pool: "luxury",
ics_lnk : "https://avlblty.com/su03.ics",
ics_txt : "",
},
SU11: {
enabled: true,
pool: "comfort",
ics_lnk : "https://avlblty.com/su11.ics",
ics_txt : "",
},
SU12: {
enabled: true,
pool: "luxury",
ics_lnk : "https://avlblty.com/su12.ics",
ics_txt : "",
},
};
If the properties under the which the rooms are returned are important, we need to add those into the room objects, like this
const rooms = Object.keys(data).map(id => ({
id,
...data[key],
}));
Otherwise, we can have all the rooms by simply calling
const rooms = Object.values(data);
Now that we have the rooms, we have to filter the get the ones with pool
equals to luxury
const luxuryRooms = rooms.filter(room => room.pool === 'luxury');
Eventually you can add a new property with
const updatedRooms = luxuryRooms.map(room => ({
...room,
newProperty: 'New Value',
}));
With lodash
:
var _ = require('lodash')
_(rooms)
.values()
.filter(r => r.pool == poolName)
.value()
Output:
[ { enabled: true,
pool: 'luxury',
ics_lnk: 'https://avlblty.com/su02.ics',
ics_txt: '' },
{ enabled: true,
pool: 'luxury',
ics_lnk: 'https://avlblty.com/su03.ics',
ics_txt: '' },
{ enabled: true,
pool: 'luxury',
ics_lnk: 'https://avlblty.com/su12.ics',
ics_txt: '' } ]
Here's a solution that will work in most modern browsers. The result is a new object with a new property on the items from the input object matching your filter.
Instead of hardcoding the function to work with one filter I've made a function ( addPropToFiltered()
) that accepts parameters for the property/value you want to filter on, and parameters for adding a new value.
This mutates the original rooms
object, but can also be easily changed to create a new object (and leave rooms
as is).
The function works like this;
addPropToFiltered(inputObject, filterProp, filterValue, newProp, newPropValue);
For your particular question we would use this as:
addPropToFiltered(rooms, "pool", "luxury", "newProp", "New Value");
which would add a new property of newProp
with a value of New Value
to each room matching pool: "luxury"
.
const addPropToFiltered = function(rooms, prop, filter, newProp, newValue) { return Object.keys(rooms).reduce(function(result, id) { const room = rooms[id]; // Add new property if applicable if (room[prop] === filter) { room[newProp] = newValue; } result[id] = room; return result; }, {}) } const rooms = { SU01: { enabled: true, pool: "comfort", ics_lnk: "https://avlblty.com/su01.ics", ics_txt: "", }, SU02: { enabled: true, pool: "luxury", ics_lnk: "https://avlblty.com/su02.ics", ics_txt: "", }, SU03: { enabled: true, pool: "luxury", ics_lnk: "https://avlblty.com/su03.ics", ics_txt: "", }, SU11: { enabled: true, pool: "comfort", ics_lnk: "https://avlblty.com/su11.ics", ics_txt: "", }, SU12: { enabled: true, pool: "luxury", ics_lnk: "https://avlblty.com/su12.ics", ics_txt: "", } }; console.log(addPropToFiltered(rooms, "pool", "luxury", "newProp", "New Value")); console.log(rooms)
The following code is ES2015 and clear in that it does not mutate any objects ( rooms
is completely untouched):
const addProperties = (rooms, pool, properties) => Object .keys(rooms) // take the keys "SU01", "SU02",... .filter(key => rooms[key].pool === pool) // take only keys with matching pool .reduce((newRooms, key) => ({ ...newRooms, [key]: { ...rooms[key], ...properties } // add properties to room }), rooms); // take "rooms" and update all changed rooms, which results in "newRooms" const rooms = { SU01: { enabled: true, pool: "comfort", ics_lnk : "https://avlblty.com/su01.ics", ics_txt : "", }, SU02: { enabled: true, pool: "luxury", ics_lnk : "https://avlblty.com/su02.ics", ics_txt : "", }, SU03: { enabled: true, pool: "luxury", ics_lnk : "https://avlblty.com/su03.ics", ics_txt : "", }, SU11: { enabled: true, pool: "comfort", ics_lnk : "https://avlblty.com/su11.ics", ics_txt : "", }, SU12: { enabled: true, pool: "luxury", ics_lnk : "https://avlblty.com/su12.ics", ics_txt : "", } }; const result = addProperties(rooms, "luxury", { newProperty: "new value" }); console.log(result);
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.