array.push to an array within an array - javascript

I'm trying to push JSON data to an array within an array. The problematic difference to other examples of this I can find is that both arrays are being built by a loop which I believe is the reason for the error I'm receiving. TypeError: Cannot call method 'push' of undefined
Here's a somewhat minimal example of what I'm trying to achieve.
var json = {origin: data.origin.name, destination: data.destination.name, trips: []};
for (var i = 0; i < data.trips.length; i++) {
var departure = data.trips[i].dep.time;
var arrival = data.trips[i].arr.time;
json.trips.push({departure: departure, arrival: arrival, nodes: []});
for (var j = 0; j < data.trips[i].legs.length; j++) {
json.trips.nodes.push({test: 'test'});
}
}
The output I'm trying to create should be looking like this.
{
origin: origin,
destination: destination,
trips: [
{
departure: departure,
arrival: arrival,
nodes: [
{test: test},
{test: test},
{test: test}
]
},
{
departure: departure,
arrival: arrival,
nodes: [
{test: test},
{test: test},
{test: test}
]
}
]
}
The test nodes are nonsensical, sure, but shouldn't adding them in this way be possible?

The line:
json.trips.nodes.push({test: 'test'});
should be:
json.trips[i].nodes.push({test: 'test'});

json.trips.nodes is indeed undefined. I believe you want to add it to the new item in the trip loop?
var json = {origin: data.origin.name, destination: data.destination.name, trips: []};
for (var i = 0; i < data.trips.length; i++) {
var newNode = {
departure: data.trips[i].dep.time,
arrival: data.trips[i].arr.time,
nodes: []
};
for (var j = 0; j < data.trips[i].legs.length; j++) {
newNode.nodes.push({test: 'test'});
}
json.trips.push(newNode);
}

var json = {origin: data.origin.name, destination: data.destination.name, trips: []};
for (var i = 0; i < data.trips.length; i++) {
var departure = data.trips[i].dep.time;
var arrival = data.trips[i].arr.time;
var trip = {departure: departure, arrival: arrival, nodes: []}
for (var j = 0; j < data.trips[i].legs.length; j++) {
trip.nodes.push({test: 'test'});
}
json.trips.push(trip);
}

Related

Best way to merge two objects on a matching key-value pair

I'm having trouble making two objects into one on a matching key.
I have two objects coming from 2 apis and there is one matching key in the objects.
I want to iterate over them and if the storeId matches in both objects, I want to merge the two together as seen in the perfectObject.
I have tried the spread operator, Object.assign, for...in loop instead of the for loop seen here, but found close to none success.
Thanks for the help!
const logistics = [{
logisticsId: "L5E69E26D8FCAE",
storeId: 409388,
logisticsDate: "2020-03-12T07:19:09.000Z",
}, ];
const stores = [{
storeId: 409388,
ka: 0,
country: "ru",
name: "test",
city: "Moscow",
cxw: 1,
cx: 1,
plz: 22448,
}, ];
const perfetObject = {
storeId: 409388,
ka: 0,
country: "ru",
name: "test",
city: "Moscow",
cxw: 1,
cx: 1,
plz: 22448,
"storeId": 409388,
logisticsId: "L5E69E26D8FCAE",
storeId: 409388,
logisticsDate: "2020-03-12T07:19:09.000Z",
};
"logisticsId": "L5E69E26D8FCAE",
let d = {};
}
for (let i = 0; i < logistics.length; ++i) {
for (let k = 0; k < stores.length; ++k) {
if (logistics.storeId === stores.storeId) {
d = {
...stores.name,
...stores.city,
...logistics.logisticsId,
};
}
}
let d = {}
console.log(d);
Leaving aside the nested for loop (there are better data structures for you to take advantage of that make this unnecessary), the easiest method would be to use Object.assign() or the spread operator, especially if the key names are guaranteed to never conflict.
const logistics = [{
logisticsId: "L5E69E26D8FCAE",
storeId: 409388,
logisticsDate: "2020-03-12T07:19:09.000Z",
}, ];
const stores = [{
storeId: 409388,
ka: 0,
country: "ru",
name: "test",
city: "Moscow",
cxw: 1,
cx: 1,
plz: 22448,
}, ];
for (let i = 0; i < logistics.length; ++i) {
for (let k = 0; k < stores.length; ++k) {
if (logistics[i].storeId === stores[k].storeId) {
console.log(Object.assign({}, logistics[i], stores[k]));
}
}
}
This assumes all store IDs are valid (e.g. have the expected store data) and all logistics elements have a valid store defined.
This is a working example answer from a reddit user u/albedoa:
const storesByStoreId = stores.reduce(
(obj, store) => {
if (!obj.hasOwnProperty(store.storeId)) {
obj[store.storeId] = store;
}
return obj;
},
{}
);
const perfectArray = logistics.map(logistic => ({
...storesByStoreId[logistic.storeId],
...logistic
}));
This way, it combines the two as supposed to, or returns the object itself if there is no match.

How can I delete all objects in a json array by its keyword

I have json like this:
json = [
{
"value1":"3863",
"value2":"4567"
},
{
"value1":"4456",
"value2":"87687"
},
{
"value1":"98494",
"value2":"4534"
},
]
What I need is to delete value2 so the json would look like:
json = [
{
"value1":"3863"
},
{
"value1":"4456"
},
{
"value1":"98494"
},
]
I have tried to use
for(var i = 0; i < json.length; i++)
{
delete json["value2"];
}
but it doesn´t work.
Is there any way of doing that ?
const json = [
{
"value1":"3863",
"value2":"4567"
},
{
"value1":"4456",
"value2":"87687"
},
{
"value1":"98494",
"value2":"4534"
},
];
json.forEach(item => delete item.value2);
use map.
json = [
{
"value1":"3863",
"value2":"4567"
},
{
"value1":"4456",
"value2":"87687"
},
{
"value1":"98494",
"value2":"4534"
}
];
console.log(json.map(({value1}) => ({value1})));
With your current syntax:
for(var i = 0; i < json.length; i++)
{
delete json[i].value2;
}
You just have missed i usage in accessing json array elements:
for(var i = 0; i < js.length; i++)
{
delete json[i]["value2"];
}
You forgot the iterator i:
delete json[i]["value2"];
var json = [
{
"value1":"3863",
"value2":"4567"
},
{
"value1":"4456",
"value2":"87687"
},
{
"value1":"98494",
"value2":"4534"
},
];
for(var i = 0; i < json.length; i++) {
delete json[i]["value2"];
}
console.log(json);

Find all keys inside array inside object of object

I have this object (i can not change it, it cames from an outside webservice) and I want to get all the ids, (structure inside data may change)
data: {
consoles:[
{
name:'',
id:''
},
{
name:'',
id:''
}
],
games:[
{
name:'',
id:''
},
{
name:'',
id:''
}
],
accesories:[
{
name:'',
id:''
},
{
name:'',
id:''
}
]
}
I was trying to get all the keys of the object with Object.keys(data) and after that do a for to try to print it
var keys = Object.keys(data);
for(var j = 0; j < keys.length; j++){
console.log(keys[j]);
for(var i = 0; i < data.keys[j].length; i++){
console.log(data.keys[j].id)
}
}
Try to replace the data.keys[j] with:
data[keys[j]]
So this gives you with:
var keys = Object.keys(data);
for(var j = 0; j < keys.length; j++){
console.log(keys[j]);
for(var i = 0; i < data.keys[j].length; i++){
console.log(data[keys[j]].id)
}
}
try this:-
var productsKeys = Object.keys(data);
for(var j = 0; j < productsKeys.length; j++){
for(var i = 0; i < data[productsKeys[j]].length; i++){
console.log(data[productsKeys[j]][i].id)
}
}
Demo
for(var i=0; i<data.consoles.length;i++){
console.log( data.consoles[i].id);
}
for(var i=0; i<data.games.length;i++){
console.log( data.games[i].id);
}
for(var i=0; i<data.accessories.length;i++){
console.log( data.accessories[i].id);
}
If consoles,games,accessories arrays have laways the same length we can use only one for.
here is what my try is how can you achieve this
data = {
consoles:[
{
name:'',
id:''
},
{
name:'',
id:''
}
],
games:[
{
name:'',
id:''
},
{
name:'',
id:''
}
],
accesories:[
{
name:'',
id:''
},
{
name:'',
id:''
}
]
}
$.each(data,function(key,val){
$.each(data[key],function(k,v){
$.each(v,function(kf,vf){
console.log(kf + "---->" + vf);
});
});
});

Split array of objects into new array or objects based on age value

Split array of objects into new array or objects based on age value in Javascript
var items = [
{name:"Foo", age:16, color:"w"},
{name:"Bar", age:18, color:"b"},
{name:"foo", age:16, color:"w"},
{name:"bar", age:18, color:"w"},
{name:"foobar", age:18, color:"b"},
{name:"barfoo", age:20, color:"w"}
];
How can I return a list like:
var items = [
{age:16,name:"Foo"|"foo",gender:"w"|"w"},
{age:18,name:"Bar"|"bar"|"foobar",gender:"b"|"w"|"b"},
{age:20,name:"barfoo",gender:"w"}
];
I have worked but i got output with 'undefined' in name. Below is my code.
var data = [{age: 21,name: "Walter",color: "black"},{age: 25,name: "sentinel",color: "black"
},{age: 21,name: "Micah",color: "purple"},{age: 25,name: "mike",color: "black"},{age: 21,name: "Danny",color: "white"},{age: 25,name: "mike",color: "black"}];
var obj=data;
var arrayobj = obj.length;
var i, row, arr = obj, ss = {};
for (i = 0; i < arr.length; i++) {
row = arr[i];
ss[row.age] = ss[row.age] || {count: 0};
if (ss[row.age][row.age] === undefined) {
ss[row.age][row.name] = row.name;
ss[row.age]['name']+=row.name+'|';
ss[row.age]['color']+=row.color+'|';
ss[row.age]['count'] += 1;
}
}
console.table(ss);
I'm assuming you want to group the items by their age. Here is one way:
(fiddle)
items.reduce(function(buckets,item){
if(!buckets[item.age]) buckets[item.age] = [];
buckets[item.age].push(item);
return buckets;
},{});
Let's explain:
For each item, if we don't already have a 'bucket' for it, create a new empty one
Add it to the bucket
return the new updated bucket list.
The method returns an object with 3 properties: 16,18 and 20, each containing the objects with that age.
This will work. The output is in different format than one provided by exebook .
Please check and confirm. Here's a fiddle....
** UX Manager
var buckets = [];
for (var item in items) {
var currentAge = items[item].age;
if(!buckets[currentAge]) {
buckets[currentAge] = [];
for (var i in items) {
if (currentAge === items[i].age) {
buckets[currentAge].push(items[i]);
}
}
}
}
var items = [
{name:"Foo", age:16, color:"w"},
{name:"Bar", age:18, color:"b"},
{name:"foo", age:16, color:"w"},
{name:"bar", age:18, color:"w"},
{name:"foobar", age:18, color:"b"},
{name:"barfoo", age:20, color:"w"}
];
var result = [] // THIS IS THE RESULTING ARRAY THAT YOU WANT
function find(age) {
for (var i = 0; i < result.length; i++)
if (result[i].age == age) return i
return -1
}
function append(i, obj) {
result[i].name.push(obj.name)
result[i].color.push(obj.color)
}
for (var i = 0; i < items.length; i++) {
var x = find(items[i].age)
if (x < 0) result.push({ age: items[i].age, name: [items[i].name], color : [items[i].color]})
else append(x, items[i])
}
console.log(result) // PRINT THE RESULT, alternatively you can use alert(result)
The output
[ { age: 16, name: [ 'Foo', 'foo' ], color: [ 'w', 'w' ] },
{ age: 18, name: [ 'Bar', 'bar', 'foobar' ], color: [ 'b', 'w', 'b' ] },
{ age: 20, name: [ 'barfoo' ], color: [ 'w' ] } ]

JavaScript. Extract values from associative array

How can I get the values from this associative array in JavaScript?
I just need the email addresses and not the labels.
(
{
office = ("my#email.com");
home = ("ahome#anotheremail.com");
work = ("nothing#email.com");
},
{
home = ("test#test.se");
}
)
UPDATE: Prefered output in JSON would be:
{
"data": [
{
"email": "my#email.com"
},
{
"email": "ahome#anotheremail.com"
},
{
"email": "nothing#email.com"
},
{
"email": "test#test.se"
}
]
}
Thankful for all input!
What you probably meant to do is:
var x = [{
office: ("my#email.com"),
home: ("ahome#anotheremail.com"),
work: ("nothing#email.com")
},
{
home: ("test#test.se")
}]
and:
for(var j = 0; j < x.length; j++)
{
for(var anItem in x[j])
{
console.log(x[j][anItem])
}
}
// EDIT:
however, it's not the best practice to use for … in.
Maybe you could change your data structure to:
var x = [[{
value: "my#email.com",
type: "office"
},
{
value: "ahome#anotheremail.com",
type: "home"
},
{
value: "nothing#email.com",
type: "work"
}],
[{
value: "test#test.se",
type: "home"
}]];
and iterate over using:
for( var i = 0, xlength = x.length; i < xlength; i++ )
{
for( var j=0, ylength = x[i].length; j < ylength; j++ )
{
console.log(x[i][j].value);
}
}
Here's a one-liner:
console.log(Object.keys(assoc).map(k => assoc[k]));
where assoc is your associative array.
Edit
I have a better answer here.
You can 'foreach' over the object to get it's properties:
for(var j = 0; j < mySet.length; j++)
{
for(var propName in mySet[j])
{
var emailAddress = mySet[j][propName];
// Do Stuff
}
}
Answer for edited question:
var ret = {data: []};
for(var j = 0; j < x.length; j++)
{
for(var anItem in x[j])
{
ret.data.push({
email: x[j][anItem]
});
}
}
console.log(ret);
The result is kept in ret.
Is it your input in JSON format? Because if so, it's the wrong syntax. However
let _in = [
{
office : "my#email.com",
home : "ahome#anotheremail.com",
work : "nothing#email.com",
},
{
home : "test#test.se"
}
]
let _out = []
_in.forEach( record => {
_out = _out.concat(Object.values(record).map(x => new Object({email : x})))
})
console.log(_out)
for each record I extracted values and "packed" into an object with the "email" attrbiute, then I merged all those arrays obtained from the original array of records
It seems that you're looking for Object.values.

Categories

Resources