How do I loop through a JavaScript object? - javascript

I'm trying to loop through this object and modify some values however I'm getting just the key when I log it.
this.restProviderService.getMessages(this.gameService.getStepId(), this.gameService.teamId).subscribe(messages => {
console.log(messages);
for (var m in messages) {
console.log(m);
}
});
console.log(messages)
[
{
"id": "3",
"chatId": "1_1",
"user_id": "21",
"userName": "batman",
"msg": "banananananana",
"createdAt": "1632507755"
},
{
"id": "2",
"chatId": "1_1",
"user_id": "31",
"userName": "jennyg",
"msg": "asdfasdfasdf",
"createdAt": "1632507721"
}
]
Console.log(m)
0
1

A for in loop in JS gives you the key. What you do is
for (var m in messages) {
var message = messages[m];
console.log(message);
}
or
for (var m of messages) {
console.log(m);
}

You are looking for a for...of loop.
In Javascript, a for...in loop will return the index each iteration. (0, 1, so on)
A for...of loop will return the item at each sequential index.
for (var m of messages) {
console.log(m);
//Will log each item in the array in order
}
You could also use the array method forEach:
messages.forEach((m, index) => {
console.log(m); // Will print each object
console.log(index); // 0, 1, 2
});
Relevant MDN
You may also be having trouble because you are dealing with an "array-like object", which can be returned from some methods. Here are some ways to convert it to a usual array. But, TLDR:
let typicalArray = [...messages];
//Do stuff with typicalArray

Related

Foreach when key is not a number

In my project i push a array into a table in firebase realtime database. Firebase generate a token and not a numeric id for each array:
{
"-N2mToYDj-i8ToErmaUj": {
"anzahl": 2,
"groesse": 0.5,
"name": "getraenk1",
"preis": 5.5
},
"-N2mX3RPnDXxWMHMJScy": {
"anzahl": 1,
"groesse": "0.25",
"name": "getraenk2",
"preis": 2.2
},
"-N2mXBT8c7EKlIgyrU72": {
"anzahl": 1,
"groesse": "0.5",
"name": "getraenk3",
"preis": 3.4
},
"-N2mXZD1BoCslj81Lcya": {
"anzahl": 1,
"groesse": "1",
"name": "getraenk4",
"preis": 5.2
"-N2m_g8GutpAFqsN4WsP": {
"anzahl": 1,
"groesse": "0.33",
"name": "getraenk5",
"preis": 3.2
},
}
How can i work with each object when the key value is not numeric. ForEach() does not work for me.
If you just care about the values, wrap the result in Object.values. If you care about the keys also, wrap the result in Object.entries instead.
const data = {"-N2mToYDj-i8ToErmaUj":{"anzahl":2,"groesse":0.5,"name":"getraenk1","preis":5.5},"-N2mX3RPnDXxWMHMJScy":{"anzahl":1,"groesse":"0.25","name":"getraenk2","preis":2.2},"-N2mXBT8c7EKlIgyrU72":{"anzahl":1,"groesse":"0.5","name":"getraenk3","preis":3.4},"-N2mXZD1BoCslj81Lcya":{"anzahl":1,"groesse":"1","name":"getraenk4","preis":5.2},"-N2m_g8GutpAFqsN4WsP":{"anzahl":1,"groesse":"0.33","name":"getraenk5","preis":3.2}};
Object.values(data).forEach(value => console.log("value", value));
console.log("===================");
Object.entries(data).forEach(([key, value]) => console.log("key", key, "value", value));
Looks like you're getting back an object not a list which is why forEach isn't working. You would need to loop through the keys of the returned object and pull the corresponding record that way.
You can do something like this to loop through the keys:
var object = {"one":"data-1","two":"data-2"}
var keys = Object.keys(object)
keys.forEach(function(key){
console.log(key);
console.log(object[key])
})
Lets say your data stored in test object.
you can use Object function in javascript to work with any object. For accessing all key you can try this:
Object.keys(test).map(key => { // key in here can be for example -N2mToYDj-i8ToErmaUj
const data = test[key] // this is the full object that each key points to
/*
{
"anzahl": 2,
"groesse": 0.5,
"name": "getraenk1",
"preis": 5.5
}
*/
})

Loop into Array of Objects comparing two arrays - PUG (Jade)

I am trying in Javascript, using PUG template (if possible), to compare two arrays and when I find a correspondance in IDs, display some particular elements.
// First Array : I iterate over "hearts" object
// Called in PUG : - const user
[
{
"hearts": [
"5e70c63a94b27b164c9b897f",
"5e723c75e4bfdf4f58c55e32"
],
"_id": "5e6bb1189978fd5afc98c57a",
"email": "catherine#catherine.com",
"name": "Catherine",
"photo": "0121b7fe-b2ae-4e75-979d-7dea1a432855.jpeg",
"__v": 0
},
{
"hearts": [
"5e723c75e4bfdf4f58c55e32"
],
"_id": "5e6bc41f5915e3d2980a5174",
"email": "marc#marc.com",
"name": "Marc",
"photo": "4caa7bfb-6408-4893-a78b-fa6e8e5b03e7.png",
"__v": 0
}
]
// Second array : I iterate over "author.hearts" object
// Called in PUG : - const store
[{
"product": {
"categories": [
1,
2
]
},
"_id": "5e6bcc76c4022eae00e22af6",
"date": "2222-02-20T21:22:00.000Z",
"author": {
"hearts": [
"5e723c75e4bfdf4f58c55e32",
"5e70c63a94b27b164c9b897f"
],
"_id": "5e6bb1189978fd5afc98c57a",
"__v": 0
},
"created": "2020-03-13T18:09:58.086Z",
"id": "5e6bcc76c4022eae00e22af6"
}]
I want to loop over the first array, find the first ID (here 5e70c63a94b27b164c9b897f), loop over the second array and see if this ID is present within the "author.hearts" object. If it is not, carry on with the second ID and if it is present, display all the keys (tags, photos, _id, date...) from the object where the ID was found.
In my example, I have just one object in my array, but I'll be having much more later on.
Many thanks for your help
If I'm understanding correctly you can do something like this. Loop through all your users and when you find their id in author.hearts stop the loop there and return the object the user's _id was found in.
var resultFound = undefined;
try {
user.forEach((el) => {
const id = el._id;
const result = store.find(el => el.author.hearts.includes(id));
if (result) {
resultFound = result;
throw resultFound;
}
});
} catch (e) {
if (e !== resultFound) {
throw e;
}
}

Proper way to iterate over two dimensional json

I have a two dimensional json that looks like:
[[{"ID":1,"Name":"....","Ct":123, "Time":"2018-05-07T00:00:00"},
{"ID":2,"Name":"....","Ct":123, "Time":"2018-05-07T00:01:00"}],
[{"ID":3,"Name":"....","Ct":123, "Time":"2018-05-07T00:02:00"},
{"ID":4,"Name":"....","Ct":123, "Time":"2018-05-07T00:03:00"}]]
It is serialized from C# object. Anyway I try to iterate over this json like:
for (var key in data) // first loop
{
var item = data[key];
for (var key2 in item) // second loop
{
// some code...
}
}
Where the first loop should iterate two times: during first iteration the second loop should iterate over two objects with IDs 1 and 2; and during second iteration over objects with IDs 3 and 4.
I guess the problem is that first loop doesn't have Key because first loop iterates only one time and second loop iterates over objects with IDs 1,2,3,4.
How can I iterate over this as two dimensional tab then?
[EDIT]
I made a mistake during iterating inside second loop and it looked like it doesn't iterate. The solution above is correct.
For loop should work but you can also use maps/forEach/for-of to iterate over arrays:
var input = [
[{"ID":1,"Name":"....","Ct":123, "Time":"2018-05-07T00:00:00"},
{"ID":2,"Name":"....","Ct":123, "Time":"2018-05-07T00:01:00"}],
[{"ID":3,"Name":"....","Ct":123, "Time":"2018-05-07T00:02:00"},
{"ID":4,"Name":"....","Ct":123, "Time":"2018-05-07T00:03:00"}]
];
input.map(outElem => {
console.log('======== outter ========');
outElem.map(inElem => {
console.log('======== inner ========');
console.log(inElem.ID);
});
});
// Output:
======== outter ========
======== inner ========
1
======== inner ========
2
======== outter ========
======== inner ========
3
======== inner ========
4
Or forEach:
input.forEach(outElem => {
console.log('======== outter ========');
outElem.forEach(inElem => {
console.log('======== inner ========');
console.log(inElem.ID);
});
});
Or for of:
for (const outElem of input) {
console.log('======== outter ========');
for (const inElem of outElem) {
console.log('======== inner ========');
console.log(inElem.ID);
}
}
var data = [
[{
"ID": 1,
"Name": "....",
"Ct": 123,
"Time": "2018-05-07T00:00:00"
},
{
"ID": 2,
"Name": "....",
"Ct": 123,
"Time": "2018-05-07T00:01:00"
}
],
[{
"ID": 3,
"Name": "....",
"Ct": 123,
"Time": "2018-05-07T00:02:00"
},
{
"ID": 4,
"Name": "....",
"Ct": 123,
"Time": "2018-05-07T00:03:00"
}
]
];
for (var key in data) // first loop
{
var item = data[key];
console.log('======== outter ========');
for (var key2 in item) // second loop
{
console.log('======== inner ========');
console.log(item[key2].ID);
}
}

JavaScript - Find an object among an array of objects, inside an array of objects

I'm using Vue, lodash, etc.
{
"street": {
"id": "1",
"streetName": "test",
"buildings": [
{
"id": "1",
"buildingName": "test"
}
]
}
}
I have a setup similar to this. This is a singular object, I basically have an array of these.
All I get is a building.id value.
From it, I need to be able to find the building it belongs to, and there isn't any direct list of buildings for me to access.
Currently
I'm using a nested loop to loop through each site until I find the one that has a building with that id. I don't know if I'm doing it correctly, it doesn't feel correct.
for(var i = 0; i < streets.length; i++){
for(var x = 0; x < streets[i].buildings.length;x++){
if(streets[i].buildings[x].id == '2aec6bed-8cdd-4043-9041-3db4681c6d08'){
}
}
}
Any tips? Thanks.
You can use a combination of filter and some methods, like this:
var result = streets.filter(function(s) {
return s.street.buildings.some(function(b) {
return b.id === searchedId;
});
});
Using .some() method will return true if any building of the iterated buildings has the searchedId.
Using .filter() will filter the streets array to return only street object where the call of some() method on its buildings will return true, in other words which meets the condition of having an idequal to searchedId.
Demo:
var streets = [{
"street": {
"id": "1",
"streetName": "test",
"buildings": [{
"id": "1",
"buildingName": "test"
}]
}
}, {
"street": {
"id": "1",
"streetName": "test",
"buildings": [{
"id": '2aec6bed-8cdd-4043-9041-3db4681c6d08',
"buildingName": "test"
}]
}
}];
var searchedId = '2aec6bed-8cdd-4043-9041-3db4681c6d08';
var result = streets.filter(function(s) {
return s.street.buildings.some(function(b) {
return b.id === searchedId;
});
});
console.log(result);
If you're trying to get all the buildings in all streets by a buildingId, this solves the problem:
streetsList.map(streetItem => streetItem.street.buildings.find(building => building.id === searchedBuildingId)).filter(v => v);
.filter(v => v) is for filtering out falsy values since we want a clean result here.
If there can be more than a single building in a street with the same id, then use .some instead of .find in the example.
Presumably you have a streets object that contains street objects, like:
var streets = [
street :{ ... },
street :{ ... },
...
];
So you need to step into each street and iterate over the buildings. A for loop should be fairly efficient since it can return as soon as it finds the building. I don't think any of the built-in looping methods will do that.
The code in the OP won't work, as streets[i].buildings must be streets[i].streets.buildings and if(streets[i].buildings[x].id must be if(streets[i].street.buildings[x].id.
Below is a working for loop version, there's also a version using recent Array methods which are very much slower even on a very small dataset. According to jsperf, the for loop version is about 100 times faster in Safari, 10 times faster in Firefox and 50 times faster in Chrome.
I also think the for loop code is much more readable and therefore maintainable.
var streets = [{
"street": {
"id": "1",
"streetName": "test",
"buildings": [{
"id": "1",
"buildingName": "test"
}, {
"id": "2",
"buildingName": "test"
}]
}
}, {
"street": {
"id": "2",
"streetName": "test",
"buildings": [{
"id": "3",
"buildingName": "test"
}]
}
}
];
function getBldById(data, id) {
for (var i=0, iLen=streets.length; i<iLen; i++) {
var street = streets[i].street;
for (var j=0, jLen=street.buildings.length; j<jLen; j++) {
if (street.buildings[j].id == id) {
return street.buildings[j];
}
}
}
return null;
}
console.log(getBldById(streets, '1'));
function getBldById2(data, id) {
return data.map(streetObj =>
streetObj.street.buildings.find(building =>
building.id === id)
).filter(v => v)[0];
}
console.log(getBldById2(streets, '1'));
You might be missing street property, right?
I mean it should be: streets[i].street.buildings[x].id

How to remove key from Array of Object

I have Array objects like below , How to convert this format into Array of objects and remove key.
{
"9417702107": {
"name": "Sunny",
"phone": "9417702107",
"exists": true
},
"8826565107": {
"name": "Gurwinder",
"phone": "8826565107",
"exists": true
}
}
How to convert this into below format using javascript:
[{
"name": "Sunny",
"phone": "9417702107",
"exists": true
}, {
"name": "Gurwinder",
"phone": "8826565107",
"exists": true
}]
Use a simple loop:
array = [];
for (var key in obj) {
array.push(obj[key]);
}
As in the other answer, there's no guarantee that the elements of the array will be in the same order as in the object.
simply try this
var output = Object.keys(obj).map(function(key){
return obj[key];
})
Note that there is no guarantee that order of items in output array will be same as in the order key-values in your object as you see it.
if the order is important, then put an new attribute called order in the object itself
var obj {
"9417702107":
{
"name": "Sunny",
"phone": "9417702107",
"exists": true,
"order_sequence" : 1
},
"8826565107": {
"name": "Gurwinder",
"phone": "8826565107",
"exists": true,
"order_sequence" : 1
}
}
and then after converting to array, you can sort on the order_sequence
var output = Object.keys(obj).map(function(key){
return obj[key];
}).sort( function(a,b){
return a.order_sequence - b.order_sequence;
});
Use Object.keys and for-cycle.
var keys = Object.keys(input), output = [];
for (var i = 0, length = keys.length; i < length; ++i)
ouptput.push(input[keys[i]]);
console.log(output);
Some tips:
- Cycles in this case gives move performance than map function, because in today JS engines: fewer functions calls, greater performance.
- For-each (for (var k in input) {}) is slower than Object.keys and cycle for/while.
This is acceptable for today implementation Google V8 and Mozilla SpiderMonkey.

Categories

Resources