Javascript merge an object and an array - javascript

My problem is to merge an object and an array of objects.
Here's my object:
{
model1: ["model1-coupe", "model1-hatchback", "model1-cabriolet"],
model2: ["model2-coupe","model12-hatchback","model2-cabriolet"],
model3: ["model3-coupe","model4-hatchback","model4-cabriolet"]
}
Here's my array of objects:
[
{image: "/path/to/image/model1.jpg"},
{image: "/path/to/image/model2.jpg"},
{image: "/path/to/image/model3.jpg"}
]
I'd like to merged them like that:
[
{
image: "/path/to/image/model1.jpg",
model1: ["model1-coupe", "model1-hatchback", "model1-cabriolet"]
},
{
image: "/path/to/image/model2.jpg",
model2: ["model2-coupe", "model2-hatchback", "model2-cabriolet"]
},
{
image: "/path/to/image/model3.jpg",
model3: ["model3-coupe", "model3-hatchback", "model3-cabriolet"]
}
]
How do I do that? I can use either JavaScript or Underscore.
Thanks in advance
EDIT: see how the merging result would actually be:
[
{
image: "/path/to/image/model1.jpg",
cars: ["model1-coupe", "model1-hatchback", "model1-cabriolet"]
},
{
image: "/path/to/image/model2.jpg",
cars: ["model2-coupe", "model2-hatchback", "model2-cabriolet"]
},
{
image: "/path/to/image/model3.jpg",
cars: ["model3-coupe", "model3-hatchback", "model3-cabriolet"]
}
]

for (var i = 0, key; i < modelArray.length; i++) {
modelArray[i].cars = modelObject[Object.keys(modelObject)[i]];
}
This will loop the array and add the property to the object. This assumes that the object properties are all in the proper order.
In each iteration, it loops up which property it's up to using Object.keys(). Then, it sets that key of the object in the array to that property of the model object.

You can do something like
var models = {
model1: ["model1-coupe", "model1-hatchback", "model1-cabriolet"],
model2: ["model2-coupe", "model12-hatchback", "model2-cabriolet"],
model3: ["model3-coupe", "model4-hatchback", "model4-cabriolet"]
}
var images = [{
image: "/path/to/image/model1.jpg"
}, {
image: "/path/to/image/model2.jpg"
}, {
image: "/path/to/image/model3.jpg"
}]
for (var key in models) {
if (models.hasOwnProperty(key)) {
var idx = +key.match(/\d+$/)[0] - 1;
images[idx][key] = models[key]
}
}
console.log(images)

try something like this:
var result = [];
var models = {
// your models object
}
var images = [
// your images array
];
for(var i=0, key in models) {
var model = models[key];
var image = images[i++];
result.push( { image: image, model: model } );
}

Related

adding another key and value to an object inside an array with JS

So I currently have a bunch of objects inside an array like below. However, I'm now trying to write a function that allows me to add another key|value into the object that was added last.
My current idea is using the arrayname.length - 1 to work out the position of the object within the array.
Would I need to create a temporary array to store the new object and then set (tempArray = oldArray) at the end of the function or would I concatinate them both?
const state = [
{
userId: 1,
},
{
Name: name,
},
{
age: 52,
},
{
title: "et porro tempora",
}]
this is the current code
let objects = [];
const addParent = (ev) =>{
ev.preventDefault();
// getting the length of the objects array
let arrayLength = objects.length;
// if the length of the array is zero - empty or one then set it to default zero
// else if there is objects stored in the array minus 1 to get the array position
if(arrayLength <= 0){
arrayLength = 0;
}else{
arrayLength = objects.length - 1;
}
//make a temporary array to be able to push new parent into an existing object
var tempObjects = []
for (var index=0; index<objects.length; index++){
}
//create a new parent object key : value
let parent = {
key: document.getElementById('key').value,
value: document.getElementById('value').value
}
//push parent object key and value into object
//objects.push(parent);
}
document.addEventListener('DOMContentLoaded', () => {
document.getElementById('btn1').addEventListener('click', addParent);
});
There are multiple ways to do this.
Try this one
var objects = [{
name: "1"
}];
const addParent = (ev) => {
let parent = {
key: "some value",
value: "some value"
}
objects = Array.isArray(objects) ? objects : [];
let lastObjectIndex = objects.length - 1;
lastObjectIndex = lastObjectIndex > -1 ? lastObjectIndex : 0
objects[lastObjectIndex] = { ...objects[lastObjectIndex],
...parent
}
}
I think You want to add new value to last object of the array
Method 1
const state = [
{
userId: 1,
},
{
Name: name,
},
{
age: 52,
},
{
title: "et porro tempora",
}]
state[state.length - 1].newKey = "value"
console.log(state)
Method 2
const state = [
{
userId: 1,
},
{
Name: name,
},
{
age: 52,
},
{
title: "et porro tempora",
}]
// 1st method
state[state.length - 1] = {
...state[state.length - 1] ,
newKey : "value"
}
console.log(state)
You can probably use something like this:
const a = [
{ "a" : "a" },
{ "b" : "b" }
]
const c = a.map((obj, index) => {
if (index === a.length -1) {
return { ...obj, newProp: "newProp" }
}
return obj;
});
console.log(c)
This will add property on the last object using spread operator, you can look it up if you are new to JS but basically it will retain all the existing property and add the newProp to the object

Not able to add key value pair in a json object from a json object

I want to add key value pair to my json object from another json object.
I tried to read many stackoverflow similar questions but none of those solutions work in my case.
const oValues = {
action: "Open Browser & Login",
password: "something",
url: "https://***manage",
user: "user1",
}
var mElementsData = {
pages: [{
groups: [{
elements: [{}]
}]
}]
};
for (var key in oValues) {
if (oValues.hasOwnProperty(key)) {
mElementsData.pages.groups.elements["label"] = key;
mElementsData.pages.groups.elements["value"] = oValues[key];
}
}
console.log(mElementsData);
Your nested properties are not objects, but arrays of objects, so you cannot access them by dot notation. You can access them by index, here is an example:
const oValues = {
action: "Open Browser & Login",
password: "something",
url: "https://***manage",
user: "user1",
}
var mElementsData = {
pages: [{
groups: [{
elements: []
}]
}]
};
for (var key in oValues) {
if (oValues.hasOwnProperty(key)) {
const element = {
label: key,
value: oValues[key]
};
mElementsData.pages[0].groups[0].elements.push(element);
}
}
console.log(mElementsData);
Your pages, groups and elements elements are all arrays of objects, so you need to reference the specific array element ([0]) to set the value:
var mElementsData = {
pages: [{
groups: [{
elements: [{}]
}]
}]
};
var oValues = {
key: "value"
};
for (var key in oValues) {
if (oValues.hasOwnProperty(key)) {
mElementsData.pages[0].groups[0].elements[0]["label"] = key;
mElementsData.pages[0].groups[0].elements[0]["value"] = oValues[key];
}
}
console.log(mElementsData);
Pages and groups are array so you have to loop over and bind the object with key and value pair
var mElementsData = {
pages: [{
groups: [{
elements: [{}]
}]
}]
};
var oValues = {
action: "Open Browser & Login",
password: "something",
url: "https://***manage",
user: "user1",
}
for (var key in oValues) {
if (oValues.hasOwnProperty(key)) {
for (let i = 0; i < mElementsData.pages.length; i++) {
let pages = mElementsData.pages[i]
for (let j = 0; j < pages.groups.length; j++) {
pages.groups[j].elements[j][key] = oValues[key]
}
}
}
}
console.log(mElementsData)

How to iterate through an object containing objects?

My object:
"hockey": {
stats: {
skaters: {
regular: [
{name: "stat1", key: "statkey1"}
{name: "stat2", key: "statkey2"}
{name: "stat3", key: "statkey3"}
]
},
goalies: {
regular: [
{name: "stat1", key: "statkey4"}
{name: "stat2", key: "statkey5"}
{name: "stat3", key: "statkey6"}
]
}
}
}
My code:
var stats = [];
var key = "";
for (position in sport.stats) {
for (stat_group in position) {
for (stat in stat_group) {
key = stat.key;
stats[key] = true;
}
}
}
I'm trying to use the above code to grab the property key from each object located within sport.stats.position.stat_group. Each sport has a different number of positions and stat groups, hence the triple for loop. I'm not getting any console errors it just isn't grabbing the key at all and the iterator variables aren't evaluating to objects but integers.
Here's what I want the resulting stats object to be:
{
"statkey1": true,
"statkey2": true,
"statkey3": true,
...
}
Hope you guys can help! Thanks!
The JS for...in loop iterates through the keys, not values. If you want to iterate an object fully, you can do so like this:
for (key in sports.stats) {
var position = sports.stats[key];
for (group_key in position) {
var stat_group = position[group_key];
for (stat_key in stat_group) {
stat_group[stat_key] = true;
}
}
}
For...in in javascript gives you the key of the object, not the value.
According to your logic, this is what you meant to do:
var stats = {};
var key = "";
for (position in sport.stats) {
for (stat_group in sport.stats[position]) {
for (stat in sport.stats[position][stat_group]) {
key = sport.stats[position][stat_group][stat].key;
stats[key] = true;
}
}
}

Create new array from iterating JSON objects and getting only 1 of its inner array

See jsfiddle here: https://jsfiddle.net/remenyLx/2/
I have data that contains objects that each have an array of images. I want only the first image of each object.
var data1 = [
{
id: 1,
images: [
{ name: '1a' },
{ name: '1b' }
]
},
{
id: 2,
images: [
{ name: '2a' },
{ name: '2b' }
]
},
{
id: 3
},
{
id: 4,
images: []
}
];
var filtered = [];
var b = data1.forEach((element, index, array) => {
if(element.images && element.images.length)
filtered.push(element.images[0].name);
});
console.log(filtered);
The output needs to be flat:
['1a', '2a']
How can I make this prettier?
I'm not too familiar with JS map, reduce and filter and I think those would make my code more sensible; the forEach feels unnecessary.
First you can filter out elements without proper images property and then map it to new array:
const filtered = data1
.filter(e => e.images && e.images.length)
.map(e => e.images[0].name)
To do this in one loop you can use reduce function:
const filtered = data1.reduce((r, e) => {
if (e.images && e.images.length) {
r.push(e.images[0].name)
}
return r
}, [])
You can use reduce() to return this result.
var data1 = [{
id: 1,
images: [{
name: '1a'
}, {
name: '1b'
}]
}, {
id: 2,
images: [{
name: '2a'
}, {
name: '2b'
}]
}, {
id: 3
}, {
id: 4,
images: []
}];
var result = data1.reduce(function(r, e) {
if (e.hasOwnProperty('images') && e.images.length) r.push(e.images[0].name);
return r;
}, [])
console.log(result);
All answers are creating NEW arrays before projecting the final result : (filter and map creates a new array each) so basically it's creating twice.
Another approach is only to yield expected values :
Using iterator functions
function* foo(g)
{
for (let i = 0; i < g.length; i++)
{
if (g[i]['images'] && g[i]["images"].length)
yield g[i]['images'][0]["name"];
}
}
var iterator = foo(data1) ;
var result = iterator.next();
while (!result.done)
{
console.log(result.value)
result = iterator.next();
}
This will not create any additional array and only return the expected values !
However if you must return an array , rather than to do something with the actual values , then use other solutions suggested here.
https://jsfiddle.net/remenyLx/7/

Convert object to JSON Array?

I have the following object being returned. I am counting a list of names by reading from a json file and storing the results in a new object.
{
ted: 501,
jeff: 40,
tony: 90
}
The following function creates an object with the names as properties and the count as their values.
function countNames(json){
var count = {};
for (var i = 0, j = json.length; i < j; i++) {
if (count[json[i].name]) {
count[json[i].name]++;
}
else {
count[json[i].name] = 1;
}
}
return count;
}
I need to create an array of objects that generate a result like this.
[
{
name: 'ted',
total: 501
},
{
name: 'jeff',
total: 40
}
{
name: 'tony',
total: 90
}
]
I am not sure what the best approach and most efficient way of achieving this is. Any help is appreciated.
Consider this following Javascript snippet:
for (var item in obj) {
result.push({
name: item,
total: obj[item]
});
}
Working DEMO
Output:
[
{
"name":"ted",
"total":501
},
{
"name":"jeff",
"total":40
},
{
"name":"tony",
"total":90
}
]
I don't understand how your code example relates to the question, but this turns the data in the first format into the last format:
var output = Object.keys(input).map(function(key) {
return {
name: key,
count: input[key]
}
});
it uses functional programming style, which usually leads to cleaner code.
JSBin

Categories

Resources