Issue on having an array in an JavaScript object - javascript

Can you please let me know if it is possible to pass an array into a JavaScript object like this?
var content = {
item1: "John",
item2: "Doe",
item3: { "item3_1", "item3_2", "item3_3" }
}
console.log(content);
Can you please let me know how I can access or update the items, or if not, can you please let me know how I can create a data format (Array of Array for example) to store these data?

The syntax for defining an array on a JavaScript object looks like this:
var content = {
item1: "John",
item2: "Doe",
item3: ["item3_1", "item3_2", "item3_3"]
};
You're not "passing" the array into the object, you're simply defining one of the properties to be an array. Any nested data inside that would take the same form that an object or another array would:
var foo = {
arr: [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
};
The important thing to remember is that you use '{}' for object syntax, and '[]' for array syntax. You can also have objects inside that array:
var bar = {
obj_arr: [
{
name: "Tim",
age: 14,
},
{
name: "Bob",
age: 36
},
{
name: "Sue",
age: 73
}
]
};
To access one of the individual elements from the array property, use this syntax:
content.item3[0] for "item3_1"
content.item3[1] for "item3_2"
or, alternatively:
content["item3"][0] for "item3_1"
content["item3"][1] for "item3_2"
although this syntax is less common when the property name is known ahead of time. To loop through the items in that array, you can use a for loop:
for (var i = 0, l = content.item3.length; i < l; i += 1) {
console.log(content.item3[i]);
}
This is how you would console.log the items out - if you wanted to do something else with them, you would need to substitute that action for the console.log call.
Here's an updated fiddle that does what I believe you're looking for: http://jsfiddle.net/qobo98yr/5/
This is the code for printing everything out in the content object to the console:
var outputString = "";
for (var prop in content) {
outputString += (content[prop] + " ");
}
console.log(outputString);

You content variable is an object that contains:
item1: String
item2: String
item3: array
var content = {
item1: "John",
item2: "Doe",
item3: { "item3_1", "item3_2", "item3_3" }
}
If item3 is an array then is should use the array notation
var content = {
item1: "John",
item2: "Doe",
item3: ["item3_1", "item3_2", "item3_3"]
}
Now you can pass this object around and call its fields like that:
function print(obj) {
var fname = obj.item1;
var lname = obj.item2;
var array = obj.item3;
alert(array.toString());
}
where call to the function will look like
print(content);

Related

Data from the object doesn't convert when using JSON.stringify

I'm stuck in this weird issue that I'm having hard time in understanding what's doing on. When a button is clicked it calls the function onSubmit. What onSubmit function should do is stringify is the object to JSON however for me this doesn't happen. The result I get when I console.log(JSON.stringify(obj)); is [[]]. When I console.log(obj); I can see the object.
I was not able to replicate the same issue in playcode.io and codesandbox.io
async function onSubmit() {
let l = [];
l["Channel"] = undefined;
l["MetricsData"] = [
{ id: 1, name: "CPA", year: "" },
{ id: 2, name: "Average Gift", year: "" },
{ id: 3, name: "Average Gift Upgrade %", year: "" }
];
let obj = [];
l.Channel = 1;
obj.push(l);
console.log(obj);
console.log(JSON.stringify(obj)); //[[]]
}
As others have pointed in comments, you're instantiating l as an array and then attempt populating named keys (Channel, Metricsdata).
Note: Technically, arrays are objects, but they're special objects (their keys are intended to be numeric and they also have a few extra props and methods, specific to arrays - e.g: length, pop, push, slice, etc...). Use the link above to read more about arrays.
What you need to do is use l as an object (e.g: {}):
const l = {
Channel: 1,
MetricsData: [
{ id: 1, name: "CPA", year: "" },
{ id: 2, name: "Average Gift", year: "" },
{ id: 3, name: "Average Gift Upgrade %", year: "" }
]
};
// Uncomment any of the following:
// console.log('object:', l);
// console.log('stringified object:', JSON.stringify(l));
const items = [];
items.push(l);
// console.log('items:', items);
// console.log('first item:', items[0]);
console.log(JSON.stringify(items));

How to insert object via push method in javascript?

I cannot add an object via push method to javascript, my code is:
arrObj = [
{
name: "Krunal",
age: 26,
},
{
name: "Ankit",
age: 24,
},
];
function onAdd() {
return CART.push(arrObj);
}
What is the reason ?
if CART is an array, you should use .concat() instead
const newArray = CART.concat(arrObj)
as arr1.concat(arr2) will concat two arrays and return the result
whereas arr1.push(arr2) will result in an array within an array

React - Filter JSON array if key exists [duplicate]

I have an array of objects and I'm wondering the best way to search it. Given the below example how can I search for name = "Joe" and age < 30? Is there anything jQuery can help with or do I have to brute force this search myself?
var names = new Array();
var object = { name : "Joe", age:20, email: "joe#hotmail.com"};
names.push(object);
object = { name : "Mike", age:50, email: "mike#hotmail.com"};
names.push(object);
object = { name : "Joe", age:45, email: "mike#hotmail.com"};
names.push(object);
A modern solution with Array.prototype.filter():
const found_names = names.filter(v => v.name === "Joe" && v.age < 30);
Or if you still use jQuery, you may use jQuery.grep():
var found_names = $.grep(names, function(v) {
return v.name === "Joe" && v.age < 30;
});
You can do this very easily with the [].filter method:
var filterednames = names.filter(function(obj) {
return (obj.name === "Joe") && (obj.age < 30);
});
You can learn more about it on this MDN page.
You could utilize jQuery.filter() function to return elements from a subset of the matching elements.
var names = [
{ name : "Joe", age:20, email: "joe#hotmail.com"},
{ name : "Mike", age:50, email: "mike#hotmail.com"},
{ name : "Joe", age:45, email: "mike#hotmail.com"}
];
var filteredNames = $(names).filter(function( idx ) {
return names[idx].name === "Joe" && names[idx].age < 30;
});
$(filteredNames).each(function(){
$('#output').append(this.name);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="output"/>
var nameList = [
{name:'x', age:20, email:'x#email.com'},
{name:'y', age:60, email:'y#email.com'},
{name:'Joe', age:22, email:'joe#email.com'},
{name:'Abc', age:40, email:'abc#email.com'}
];
var filteredValue = nameList.filter(function (item) {
return item.name == "Joe" && item.age < 30;
});
//To See Output Result as Array
console.log(JSON.stringify(filteredValue));
You can simply use javascript :)
For those who want to filter from an array of objects using any key:
function filterItems(items, searchVal) {
return items.filter((item) => Object.values(item).includes(searchVal));
}
let data = [
{ "name": "apple", "type": "fruit", "id": 123234 },
{ "name": "cat", "type": "animal", "id": 98989 },
{ "name": "something", "type": "other", "id": 656565 }]
console.log("Filtered by name: ", filterItems(data, "apple"));
console.log("Filtered by type: ", filterItems(data, "animal"));
console.log("Filtered by id: ", filterItems(data, 656565));
filter from an array of the JSON objects:**
var names = [{
name: "Joe",
age: 20,
email: "joe#hotmail.com"
},
{
name: "Mike",
age: 50,
email: "mike#hotmail.com"
},
{
name: "Joe",
age: 45,
email: "mike#hotmail.com"
}
];
const res = _.filter(names, (name) => {
return name.name == "Joe" && name.age < 30;
});
console.log(res);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.5/lodash.js"></script>
So quick question. What if you have two arrays of objects and you would like to 'align' these object arrays so that you can make sure each array's objects are in the order as the other array's? What if you don't know what keys and values any of the objects inside of the arrays contains... Much less what order they're even in?
So you need a 'WildCard Expression' for your [].filter, [].map, etc. How do you get a wild card expression?
var jux = (function(){
'use strict';
function wildExp(obj){
var keysCrude = Object.keys(obj),
keysA = ('a["' + keysCrude.join('"], a["') + '"]').split(', '),
keysB = ('b["' + keysCrude.join('"], b["') + '"]').split(', '),
keys = [].concat(keysA, keysB)
.sort(function(a, b){ return a.substring(1, a.length) > b.substring(1, b.length); });
var exp = keys.join('').split(']b').join('] > b').split(']a').join('] || a');
return exp;
}
return {
sort: wildExp
};
})();
var sortKeys = {
k: 'v',
key: 'val',
n: 'p',
name: 'param'
};
var objArray = [
{
k: 'z',
key: 'g',
n: 'a',
name: 'b'
},
{
k: 'y',
key: 'h',
n: 'b',
name: 't'
},
{
k: 'x',
key: 'o',
n: 'a',
name: 'c'
}
];
var exp = jux.sort(sortKeys);
console.log('#juxSort Expression:', exp);
console.log('#juxSort:', objArray.sort(function(a, b){
return eval(exp);
}));
You can also use this function over an iteration for each object to create a better collective expression for all of the keys in each of your objects, and then filter your array that way.
This is a small snippet from the API Juxtapose which I have almost complete, which does this, object equality with exemptions, object unities, and array condensation. If these are things you need or want for your project please comment and I'll make the lib accessible sooner than later.
Hope this helps! Happy coding :)
The most straightforward and readable approach will be the usage of native javascript filter method.
Native javaScript filter takes a declarative approach in filtering array elements. Since it is a method defined on Array.prototype, it iterates on a provided array and invokes a callback on it. This callback, which acts as our filtering function, takes three parameters:
element — the current item in the array being iterated over
index — the index or location of the current element in the array that is being iterated over
array — the original array that the filter method was applied on
Let’s use this filter method in an example. Note that the filter can be applied on any sort of array. In this example, we are going to filter an array of objects based on an object property.
An example of filtering an array of objects based on object properties could look something like this:
// Please do not hate me for bashing on pizza and burgers.
// and FYI, I totally made up the healthMetric param :)
let foods = [
{ type: "pizza", healthMetric: 25 },
{ type: "burger", healthMetric: 10 },
{ type: "salad", healthMetric: 60 },
{ type: "apple", healthMetric: 82 }
];
let isHealthy = food => food.healthMetric >= 50;
const result = foods.filter(isHealthy);
console.log(result.map(food => food.type));
// Result: ['salad', 'apple']
To learn more about filtering arrays in functions and yo build your own filtering, check out this article:
https://medium.com/better-programming/build-your-own-filter-e88ba0dcbfae

Object preparation in JS before sending to server?

I'm trying to prepare an object to POST to my server to store some information. This object requires me to do a few GET requests depending on how the user chooses to gather all the information needed to POST. I realized I have to modify the object to actually get them into the correct value pairs in JSON, and I'm not sure if there is a better way to do it.
I'm only showing this in a simple way, but the actual matter has 6-7 very long objects, and they all needs to be modified and fit in one JSON. The server API is written this way to accept input, and I don't have any say in it.
For example:
What I get back from requests
object1: {
id: 1,
name: "table",
price: 3499
}
object2: {
id: 5,
lat: 48.56,
lng: -93.45,
address: "1080 JavaScript Street"
}
What I need it to become:
data: {
map_id: 5,
product_id: [1],
product_name: ["table"],
product_price: [3499],
start_lat: 48.56,
start_lng: -93.45,
start_address: "1080 JavaScript Street"
}
So far I just do the dumb way to just stitch them together, I just wrote this on here so it doesn't work, but should show logically what I'm thinking:
prepareDataToSend = (object1, object2) => {
//exclude uninit handling, and newObject init for arrays
let newObject = {};
newObject.map_id = object2.id;
//if there are more of object1 then I have to loop it
newObject.product_id.push(object1.id);
newObject.product_name.push(object1.name);
...etc
}
I do get the result I'm looking for, but this feels really ineffective and dumb.Not to mention this seems very unmaintainable. Is there a better way to do this? I feel like there is some techniques i'm missing.
You could use ES6 object destructuring.
let object1 = {
id: 1,
name: "table",
price: 3499
};
let object2 = {
id: 5,
lat: 48.56,
lng: -93.45,
address: "1080 JavaScript Street"
};
// declaring the new object with the new properties names.
let newObject = {
map_id: '',
product_id: [],
product_name: [],
product_price: [],
start_lat: '',
start_lng: '',
start_address: ''
};
// destructuring "object1"
({id: newObject.product_id[0],
name: newObject.product_name[0],
price: newObject.product_price[0]} = object1);
// destructuring "object2"
({id: newObject.map_id,
lat: newObject.start_lat,
lng: newObject.start_lng,
address: newObject.start_address} = object2);
console.log(newObject)
Result:
{
map_id: 5,
product_id: [1],
product_name: ["table"],
product_price: [3499],
start_address: "1080 JavaScript Street",
start_lat: 48.56,
start_lng: -93.45
}
It sounds like you need something like JQuery's or Angular's extend() function, but with a twist for sub-mapping the keys.
https://api.jquery.com/jquery.extend/
Here's a simple version of it, tweaked for your needs.
//merge the N objects. Must have a "prefix" property to configure the new keys
var extendWithKeyPrefix = function() {
if (arguments.length == 0) return; //null check
var push = function(dst, arg) {
if (typeof arg != 'undefined' && arg != null) { //null check
var prefix = arg["prefix"]; //grab the prefix
if (typeof prefix != 'undefined' && prefix != null) { //null check
for (var k in arg) { //add everything except for "prefix"
if (k != "prefix") dst[prefix+k] = arg[k];
}
}
}
return dst;
}
arguments.reduce(push);
}
Please note that the value of the last object that uses a particular key will win. For example notice that "id" in the merged object is 2, rather than 1.
var object1 = {id: 1, unique1: "One", prefix: "product_"};
var object2 = {id: 2, unique2: "Two", prefix: "product_"};
var object3 = {id: 3, unique3: "Three", prefix: "office_"};
var merged = {};
extend(merged, object1, object2);
// value of merged is...
// { product_id: 2,
// product_unique1: "One",
// product_unique2: "Two",
// office_id: 3,
// office_unique3: "Three"
// }

How to loop through an array containing objects and access their properties

I want to cycle through the objects contained in an array and change the properties of each one. If I do this:
for (var j = 0; j < myArray.length; j++){
console.log(myArray[j]);
}
The console should bring up every object in the array, right? But in fact it only displays the first object. if I console log the array outside of the loop, all the objects appear so there's definitely more in there.
Anyway, here's the next problem. How do I access, for example Object1.x in the array, using the loop?
for (var j = 0; j < myArray.length; j++){
console.log(myArray[j.x]);
}
This returns "undefined." Again the console log outside the loop tells me that the objects all have values for "x". How do I access these properties in the loop?
I was recommended elsewhere to use separate arrays for each of the properties, but I want to make sure I've exhausted this avenue first.
Thank you!
Use forEach its a built-in array function. Array.forEach():
yourArray.forEach(function (arrayItem) {
var x = arrayItem.prop1 + 2;
console.log(x);
});
Some use cases of looping through an array in the functional programming way in JavaScript:
1. Just loop through an array
const myArray = [{x:100}, {x:200}, {x:300}];
myArray.forEach((element, index, array) => {
console.log(element.x); // 100, 200, 300
console.log(index); // 0, 1, 2
console.log(array); // same myArray object 3 times
});
Note: Array.prototype.forEach() is not a functional way strictly speaking, as the function it takes as the input parameter is not supposed to return a value, which thus cannot be regarded as a pure function.
2. Check if any of the elements in an array pass a test
const people = [
{name: 'John', age: 23},
{name: 'Andrew', age: 3},
{name: 'Peter', age: 8},
{name: 'Hanna', age: 14},
{name: 'Adam', age: 37}];
const anyAdult = people.some(person => person.age >= 18);
console.log(anyAdult); // true
3. Transform to a new array
const myArray = [{x:100}, {x:200}, {x:300}];
const newArray= myArray.map(element => element.x);
console.log(newArray); // [100, 200, 300]
Note: The map() method creates a new array with the results of calling a provided function on every element in the calling array.
4. Sum up a particular property, and calculate its average
const myArray = [{x:100}, {x:200}, {x:300}];
const sum = myArray.map(element => element.x).reduce((a, b) => a + b, 0);
console.log(sum); // 600 = 0 + 100 + 200 + 300
const average = sum / myArray.length;
console.log(average); // 200
5. Create a new array based on the original but without modifying it
const myArray = [{x:100}, {x:200}, {x:300}];
const newArray= myArray.map(element => {
return {
...element,
x: element.x * 2
};
});
console.log(myArray); // [100, 200, 300]
console.log(newArray); // [200, 400, 600]
6. Count the number of each category
const people = [
{name: 'John', group: 'A'},
{name: 'Andrew', group: 'C'},
{name: 'Peter', group: 'A'},
{name: 'James', group: 'B'},
{name: 'Hanna', group: 'A'},
{name: 'Adam', group: 'B'}];
const groupInfo = people.reduce((groups, person) => {
const {A = 0, B = 0, C = 0} = groups;
if (person.group === 'A') {
return {...groups, A: A + 1};
} else if (person.group === 'B') {
return {...groups, B: B + 1};
} else {
return {...groups, C: C + 1};
}
}, {});
console.log(groupInfo); // {A: 3, C: 1, B: 2}
7. Retrieve a subset of an array based on particular criteria
const myArray = [{x:100}, {x:200}, {x:300}];
const newArray = myArray.filter(element => element.x > 250);
console.log(newArray); // [{x:300}]
Note: The filter() method creates a new array with all elements that pass the test implemented by the provided function.
8. Sort an array
const people = [
{ name: "John", age: 21 },
{ name: "Peter", age: 31 },
{ name: "Andrew", age: 29 },
{ name: "Thomas", age: 25 }
];
let sortByAge = people.sort(function (p1, p2) {
return p1.age - p2.age;
});
console.log(sortByAge);
9. Find an element in an array
const people = [ {name: "john", age:23},
{name: "john", age:43},
{name: "jim", age:101},
{name: "bob", age:67} ];
const john = people.find(person => person.name === 'john');
console.log(john);
The Array.prototype.find() method returns the value of the first element in the array that satisfies the provided testing function.
References
Array.prototype.some()
Array.prototype.forEach()
Array.prototype.map()
Array.prototype.filter()
Array.prototype.sort()
Spread syntax
Array.prototype.find()
You can use a for..of loop to loop over an array of objects.
for (let item of items) {
console.log(item); // Will display contents of the object inside the array
}
One of the best things about for..of loops is that they can iterate over more than just arrays. You can iterate over any type of iterable, including maps and objects. Make sure you use a transpiler or something like TypeScript if you need to support older browsers.
If you wanted to iterate over a map, the syntax is largely the same as the above, except it handles both the key and value.
for (const [key, value] of items) {
console.log(value);
}
I use for..of loops for pretty much every kind of iteration I do in Javascript. Furthermore, one of the coolest things is they also work with async/await as well.
for (var j = 0; j < myArray.length; j++){
console.log(myArray[j].x);
}
Here's an example on how you can do it :)
var students = [{
name: "Mike",
track: "track-a",
achievements: 23,
points: 400,
},
{
name: "james",
track: "track-a",
achievements: 2,
points: 21,
},
]
students.forEach(myFunction);
function myFunction(item, index) {
for (var key in item) {
console.log(item[key])
}
}
Looping through an array of objects is a pretty fundamental functionality. This is what works for me.
var person = [];
person[0] = {
firstName: "John",
lastName: "Doe",
age: 60
};
var i, item;
for (i = 0; i < person.length; i++) {
for (item in person[i]) {
document.write(item + ": " + person[i][item] + "<br>");
}
}
It's really simple using the forEach method since ES5+. You can directly change each property of each object in your array.
myArray.forEach(function (arrayElem){
arrayElem = newPropertyValue;
});
If you want to access a specific property on each object:
myArray.forEach(function (arrayElem){
arrayElem.nameOfYourProperty = newPropertyValue;
});
myArray[j.x] is logically incorrect.
Use (myArray[j].x); instead
for (var j = 0; j < myArray.length; j++){
console.log(myArray[j].x);
}
const jobs = [
{
name: "sipher",
family: "sipherplus",
job: "Devops"
},
{
name: "john",
family: "Doe",
job: "Devops"
},
{
name: "jim",
family: "smith",
job: "Devops"
}
];
const txt =
` <ul>
${jobs.map(job => `<li>${job.name} ${job.family} -> ${job.job}</li>`).join('')}
</ul>`
;
document.body.innerHTML = txt;
Be careful about the back Ticks (`)
this.data = [{name:"Rajiv", city:"Deoria"},{name:"Babbi", city:"Salempr"},{name:"Brijesh", city:"GKP"}];
for(const n of this.data) {
console.log(n.name)
}
This would work. Looping thorough array(yourArray) . Then loop through direct properties of each object (eachObj) .
yourArray.forEach( function (eachObj){
for (var key in eachObj) {
if (eachObj.hasOwnProperty(key)){
console.log(key,eachObj[key]);
}
}
});
Accepted answer uses normal function. So posting the same code with slight modification using arrow function on forEach
yourArray.forEach(arrayItem => {
var x = arrayItem.prop1 + 2;
console.log(x);
});
Also in $.each you can use arrow function like below
$.each(array, (item, index) => {
console.log(index, item);
});
Here's another way of iterating through an array of objects (you need to include jQuery library in your document for these).
$.each(array, function(element) {
// do some operations with each element...
});
Array object iteration, using jQuery,
(use the second parameter to print the string).
$.each(array, function(index, item) {
console.log(index, item);
});
var c = {
myProperty: [
{ name: 'this' },
{ name: 'can' },
{ name: 'get' },
{ name: 'crazy' }
]
};
c.myProperty.forEach(function(myProperty_element) {
var x = myProperty_element.name;
console.log('the name of the member is : ' + x);
})
This is one of the ways how I was able to achieve it.
I want to loop and deconstruction assignment at the same time, so code like this: config.map(({ text, callback })=>add_btn({ text, callback }))
This might help somebody. Maybe it's a bug in Node.
var arr = [ { name: 'a' }, { name: 'b' }, { name: 'c' } ];
var c = 0;
This doesn't work:
while (arr[c].name) { c++; } // TypeError: Cannot read property 'name' of undefined
But this works...
while (arr[c]) { c++; } // Inside the loop arr[c].name works as expected.
This works too...
while ((arr[c]) && (arr[c].name)) { c++; }
BUT simply reversing the order does not work. I'm guessing there's some kind of internal optimization here that breaks Node.
while ((arr[c].name) && (arr[c])) { c++; }
Error says the array is undefined, but it's not :-/ Node v11.15.0
I know it's been long but for anyone else encountering this issue, my problem is that I was looping through an array of arrays containing only one array. Like this:
// array snippet (returned from here)
} else {
callback([results])
}
And I was using the array like this
for(const result of results){
console.log(result.x)
}
As you can see, the array I wanted to iterate over was actually inside another array. removing the square brackets helped. Node JS and MySQL.

Categories

Resources