creating Object with different data - javascript

I was wondering if there's a way to create an object with changeable data.
Eg:
pearson = {
name: "",
age: 0
}
Can I do something like a loop that each time it changes these 2 variables and assign the whole object with the data into an array, but each time the object will hold the updated data?
Something like:
let pearson = { name: '', age: 20 }
const pearsonsList = [{name: 'dave', age: 20}, {name: 'jessy', age: 30}]
let arr = []
pearsonsList.forEach((e) =>{
pearson.name = e.name
pearson.age = e.age
arr.push(pearson)
})
console.log(arr[0])
/* this what arr[0] holds
{
"name": "jessy",
"age": 30
}*/
how to make arr[0] have a different value than arr[1] where the object data always get overridden ?

The main problem here is your arr is storing the reference to your pearson object, which gets modified each time you set it, even after you push them into your arr.
A solution would be to construct a new object each time before pushing it in.
const pearsonsList = [{name: 'dave', age: 20}, {name: 'jessy', age: 30}]
let arr = []
pearsonsList.forEach((e) =>{
let pearson = { name: '', age: 20 }
pearson.name = e.name
pearson.age = e.age
arr.push(pearson)
})
An optional, and cleaner solution would be to use .map instead of .forEach too
const pearsonsList = [{name: 'dave', age: 20}, {name: 'jessy', age: 30}]
let arr = pearsonsList.map((e) =>{
let pearson = { name: '', age: 20 }
pearson.name = e.name
pearson.age = e.age
return person;
})

Related

Get values by key in the Array of object

I've an array which contains the objects including various key and values. I'm going to pick out the certain values from the Array and check if the specific value is included or not in the Array.
function groupByName (contract) {
const { age } = contract;
const groups = [
{name: 'John', age: 30},
{name: 'Jack', age: 33},
{name: 'Tom', age: 40}
...
];
...
}
In order to compare the age in groups array, right now I have to use loop functions and then check one by one.
Like
groups.forEach(g => {
if (g.age === age) {
...
} else {
...
}
});
But I don't like this approach and think there are simple and effective way.
Please help me!
you can use filter to create two sublists
like this
const groups = [
{name: 'John', age: 30},
{name: 'Jack', age: 33},
{name: 'Tom', age: 40}
]
const withAge = age => groups.filter(g => g.age === age)
const withoutAge = age => groups.filter(g => g.age !== age)
const age30 = withAge(30)
const ageNot30 = withoutAge(30)
age30.forEach(g => {
console.log('do some stuff with age 30', g)
})
ageNot30.forEach(g => {
console.log('do some stuff without age 30', g)
})
maybe you can see this function
groups.some(p=>r.age===age)//if there is a object meet the criteria, return true, else return false
or read this https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/some
by the way, if you want to execute the if/else snippet in every loop, maybe you should use forEach

Take an object from an array of objects based on the max value on one of its properties

Let's say I got an array of object like this
const arr = [
{name: 'John', age: 15},
{name: 'Max', age: 17},
{name: 'Tom', age: 11},
]
How can I take just the object containing Max, 17?
This would be the result
b = [{ name: Max, age: 17 }]
or better
c = { name: Max, age: 17 }
Reduce the array to the object with highest age:
const arr = [{"name":"John","age":15},{"name":"Max","age":17},{"name":"Tom","age":11}]
const result = arr.reduce((acc, o) => !acc || o.age > acc.age ? o : acc, null)
console.log(result)
I'm using null as the default value for the Array.reduce() to prevent an error if the array is empty. However, you can check for an empty array beforehand as well:
const findMaxAge = arr => arr.length
? arr.reduce((acc, o) => o.age > acc.age ? o : acc)
: null
const arr = [{"name":"John","age":15},{"name":"Max","age":17},{"name":"Tom","age":11}]
console.log(findMaxAge(arr))
console.log(findMaxAge([]))
You can sort by age first, then the object with the highest age value will be at the start of the list:
const a = [
{name: "John", age: 15},
{name: "Max", age: 17},
{name: "Tom", age: 11},
]
const sortedByAge = a.sort((a,b) => b.age - a.age);
const highestAge = sortedByAge[0];
console.log(highestAge);
hope this code helping you
const a = [{name: 'John', age: 15},
{name: 'Max', age: 17},
{name: 'Tom', age: 11},];
const result = a.reduce((p, c) => p.age > c.age ? p : c);
console.log(result);
Using the Array.prototype.reduce() is a clean way.
this function iterates through the array one by one, at each step adding the current array value to the result from the previous step. in our case will compare the previous largest element to the current. the return value will be the object containing the largest value for the age key.
const arr = [
{name: 'John', age: 15},
{name: 'Max', age: 17},
{name: 'Tom', age: 11},
]
const largest = arr.reduce((prev, current) => (prev.age > current.age) ? prev : current)
console.log(largest);

Adding new keys and a set of values to an already existing array in javascript

I have this data:
myArray=['joe', 'sarah', 'jack', 'steph']
tempString = ' rogan'
I want to convert it to this:
myArray=[
{name: 'joe', value: 'joe rogan'},
{name: 'sarah', value: 'sarah rogan'},
{name: 'jack', value: 'jack rogan'},
{name: 'steph', value: 'steph rogan'}
]
I have tried:
myArray.map(o => ({ name: o.name }, { value: o.name + tempString });
but it doesn't work. How can I do it?
You want to return one object with both properties, so you should not be creating two separate object literals. In your case, the comma operator is causing only the last (second) one to be returned.
const myArray=['joe', 'sarah', 'jack', 'steph']
const tempString = ' rogan'
const res = myArray.map((name)=>({name,value:name+tempString}));
console.log(res);
Below snippet could help you
const myArray = ["joe", "sarah", "jack", "steph"]
const tempString = " rogan"
const res = myArray.map((name) => ({
name: name,
value: name + tempString,
}))
console.log(res)
You can also use the forEach function to iterate through arrays:
const myArray = ["joe", "sarah", "jack", "steph"]
const tempString = " rogan";
let newArray = [];
myArray.forEach((name) => newArray.push({name, value: name + tempString}));
console.log(newArray);

Get values from an array of objects

I am looping through my array to get the corresponding field value:
var someFun = function (nm) {
var names = [{name: 'joe', age: 'nine'}, {name: 'tom', age: 'ten'}];
for (var i=0; i < names.length; i++) {
if (names[i].name === nm) return names[i].age;
}
};
var username = 'tom';
var printme = someFun(username);
console.log('hey: ', printme)
How can I do the same using Object.keys(), or map, or forEach? Much cleaner and ES6 compliant.
Simply use find
([{name: 'joe', age: 'nine'}, {name: 'tom', age: 'ten'}].find( (s)=> s.name=="tom" )||{}).age //10
([{name: 'joe', age: 'nine'}, {name: 'tom', age: 'ten'}].find( (s)=> s.name=="tom2" )||{}).age //undefined
Demo
var names = [{
name: 'joe',
age: 'nine'
}, {
name: 'tom',
age: 'ten'
}];
function getAge(names, name) {
return (names.find((s) => s.name == name) || {}).age;
}
console.log(getAge(names, "tom"))
console.log(getAge(names, "tom2"))
You can use array.prototype.find:
var names = [{name: 'joe', age: 'nine'}, {name: 'tom', age: 'ten'}];
var someFun = (nm) => {
var found = names.find(el => el.name === nm);
return found && found.age || null;
}
console.log(someFun('tom'));
From Array.prototype.find()
The find() method returns the value of the first element in the array
that satisfies the provided testing function.
If there are multiples objects with the same name?
With Array.prototype.filter()
var names = [{
name: 'joe',
age: 9
},
{
name: 'tom',
age: 10
},
{
name: 'frank',
age: 9
},
{
name: 'joe',
age: 15
}
];
function getData(arr, search) {
// Filter array of objects by a search pair
return arr.filter(o => o[search[0]] === search[1]);
}
function listBy(arr, k) {
// Output values from an array of objects by a key as a comma separated string
return arr.map(o => o[k]).join(",");
}
console.log(getData(names, ["name", "joe"]));
console.log(listBy(getData(names, ["name", "tom"]), "age"));
console.log(listBy(getData(names, ["age", 9]), "name"));
IE doesn't support find, check the Browser compatibility. Maybe you don't need to support IE, but it's still a gets 3.74% of global usage as of Oct 2017. However, it does support filter.
DEMO
var users = [
{ name: "Bill", age: 'nine' },
{ name: 'Tedd', age: 'ten' }
];
function getAgeFromUsers(name) {
const arr = users.filter(u => u.name === name);
return !!arr.length ? arr[0].age : "That user ain't here";
}
console.log(getAgeFromUsers('Tedd'));
console.log(getAgeFromUsers("Lion 'O"));
var someFun = nm => {
const names = [{name: 'joe', age: 'nine'}, {name: 'tom', age: 'ten'}];
const foundName = names.find(name => name.name === nm)
return foundName ? foundName.age : null
};
This replicates what you have above. Although i would personally return the object then age the age from that instead of just returning the age.

Array of Objects in Javascript on the basis of an element

Lets Suppose I have 1000's of objects. Now I want to store objects with same name in an array So that I'll have multiple arrays having objects with same name. How can this be done in JavaScript?
Data can be like this
var input = [
{ name: 'ABC', age: 12 },
{ name: 'XYZ', age: 13 },
{ name: 'ABC', age: 14 },
{ name: 'XYZ', age: 15 },
];
var output = {};
input.forEach(function(obj) {
var array = output[obj.name];
if (!array) {
array = output[obj.name] = [];
}
array.push(obj)
})
for(name in output) {
console.log('There are ' + output[name].length + ' people named ' + name);
}
In javascript, objects aren't copied into arrays. They exist in memory and when added to a an array the reference to that object is what lives in an array.
In the following code, myObj === arr1[0] === arr2. Which means the following is true:
var myObj = {name:'Dave', age: 55};
var arr1 = [myObj];
var arr2 = [myObj];
arr2[0].age = 44;
console.log(myObj.age);
// prints 44
console.log(arr1[0].age);
// prints 44
So to get what you need, you just need to organize your data into arrays. In javascript, you can filter arrays:
// original data
var data = [
{name: 'ABC', age: 12},
{name: 'XYZ', age: 13},
{name: 'ABC', age: 14},
{name: 'XYZ', age: 15},
{name: 'XYZ', age: 16},
];
// this returns a function to be used in Array.filter to filter for objects with the specified name
function nameFilter(name) {
return function(datum) {
return datum.name === name;
}
}
// filter for each type
var abcPeople = data.filter(nameFilter('ABC'));
var xyzPeople = data.filter(nameFilter('XYZ'));
console.log(data.length);
//5
console.log(abcPeople.length);
//2
console.log(xyzPeople.length);
//3
If you run the above code, you would have 3 arrays and all object in abcPeople would also be in data such that any change to one would be reflected in the other. The same is true for xyzPeople. Just to be clear, filter creates a new array, so data is not modified.
UPDATE: Added example where lists are dynamically determined
// original data
var data = [
{name: 'ABC', age: 12},
{name: 'XYZ', age: 13},
{name: 'ABC', age: 14},
{name: 'XYZ', age: 15},
{name: 'XYZ', age: 16},
];
var sortedData = {};
data.forEach(function(datum){
// initializes an array for any unseen name
if(!sortedData[datum.name]) {
sortedData[datum.name] = [];
}
// add the datum to the list for its name
sortedData[datum.name].push(datum);
});
// all names
console.log(Object.keys(sortedData));
// "ABC", "XYZ"
// items named "ABC"
console.log(sortedData['ABC']);
// [{"name": "ABC","age": 12}, {"name": "ABC","age": 14}]

Categories