How to add two array object in same array? - javascript

For example, I have two array object with different column names and values and I want them to be at same index
let a = [{name: 'asha', age:20, mother: "sushi", father: "Nick"}]
let b = [{class: "10th", Sub: "science", Marks: 30}]
and I want to merge these into a single array like this:
[{name: 'asha', age:20, mother: "sushi", father: "Nick", class: "10th", Sub: "science"}]

You can use Array#map to combine elements at the same index with spread syntax.
let a = [{name: 'asha', age:20, mother: "sushi", father: "Nick"}], b = [{class: "10th", Sub: "science", Marks: 30, }]
let res = a.map((x, i) => ({...x, ...b[i]}));
console.log(res);

Assuming both arrays have the same length, you can use a for loop with the spread operator on corresponding elements
const combined = [];
for(let i...) {
combined.push({ ...arr1[i], arr2[i]});
}

You can use Array#forEach as follows:
const
a = [{name: 'asha', age:20, mother: "sushi", father: "Nick"}],
b = [{class: "10th", Sub: "science", Marks: 30}],
c = [];
a.forEach((val, i) => c.push({...val,...b[i]}));
console.log( c );

Related

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);

creating Object with different data

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;
})

How to extract values from certain keys from objects that are in an array

I have this array of objects:var array = [{name: "Tom", id: 123}, {name: "chris", id: 1234}, {name: "Simon", id: 111}];
I want to iterate through the 3 objects in the array and extract the name of each one, and then push that name into a new array.
This is what I thought would work:
var array = [{name: "Tom", id: 123}, {name: "chris", id: 1234}, {name: "Simon", id: 111}];
var newArrayOfNames = [];
Object.values(array).forEach(function(name){
newArrayOfNames.push(name);
});
console.log(newArrayOfNames);
you can try this:
var array = [{name: "Tom", id: 123}, {name: "chris", id: 1234}, {name: "Simon", id: 111}];
var newArrayOfNames = [];
array.forEach(function(item) {
newArrayOfNames.push(item.name);
});
console.log(newArrayOfNames);
A small change to your code:
var array = [{name: "Tom", id: 123}, {name: "chris", id: 1234}, {name: "Simon", id: 111}];
var newArrayOfNames = [];
Array.prototype.forEach.call(array, function(o){
newArrayOfNames.push(o.name);
});
console.log(newArrayOfNames);
let array = [{name: "Tom", id: 123}, {name: "chris", id: 1234}, {name: "Simon", id: 111}];
let names = []
for(let person of array) {
names.push(person.name)
}
This should work, it takes the name attribute from the "person", which is in this case an entry in your array.
IMHO, the best approach as of 2021 is as follows:
let array = [
{
name: "Tom",
id: 123
},
{
name: "chris",
id: 1234
},
{
name: "Simon",
id: 111
}
];
// Use the Array's map function to transform the elements of the array into something else
let newArrayOfNames = array.map( pValue => pValue.name );
console.log( newArrayOfNames );
The map's documentation states:
The map() method creates a new array populated with the results of calling a provided function on every element in the calling array.
This would be the most appropriate way (Provided you don't support IE anymore or you use a transpiler) since both arrays are of the same length.
If you need to omit elements I'd use the filter function for omitting those elements first and then the map function, and although that requires to iterate once through the original array and once through the filtered array, the purpose of the code is clearer for the reader of the code. Another approach is to use reduce to create another array and filter the elements in the callback given to reduce (not pushing them into the new array), this will only traverse the original array once but may lack clarity for readers depending on your code.
A small change in your existing code would have worked:
var array = [{name: "Tom", id: 123}, {name: "chris", id: 1234}, {name: "Simon", id: 111}];
var newArrayOfNames = [];
Object.values(array).forEach(function(person){ // note that person is the object on each iteration of array
newArrayOfNames.push(person.name); // object has property called name
});
console.log(newArrayOfNames); // => [ "Tom", "chris", "Simon" ]
This is the perfect use case for a .reduce(), whose goal is:
The reduce() method applies a function against an accumulator and each
element in the array (from left to right) to reduce it to a single
value.
In your case, you want to accumulate all of the names and put them into a new Array. Perfect for .reduce().
Note that the acc argument stands for accumulator, so each time you loop through a person, you make your changes to the accumulator and then pass it to the next loop.
Note: I would not recommend solving your problem using .forEach() since forEach will make changes directly to your original Array. Any changes you do, will be applied to people, and you will get a new Array back from forEach. This is why methods such as Array.prototype.map/reduce exist!
const people = [
{ name: "Tom", id: 123} ,
{ name: "chris", id: 1234} ,
{ name: "Simon", id: 111 },
];
const names = people.reduce((acc, person) => {
acc.push(person.name);
return acc;
}, []);

Merge objects on unique combinations of key-value pairs

I would like a function
combineListOnKeys(listOfObjs, listOfKeys)
that will take this:
var listOfObjs =
[
{ name: john, state: ny, age: 12}
, { name: john, state: ny, age: 22}
, { name: john, state: dc, age: 32}
, { name: john, state: dc, age: 42}
, { name: paul, state: ca, age: 52}
]
var listOfKeys = ["name", "state"]
and returns this:
combineListOnKeys(listOfObjs, listOfKeys)
[
{ "name": john, "state": ny, "age": [12, 22]}
,{ "name": john, "state": dc, "age": [32, 42]}
,{ "name": paul, "state": ca, "age": [52]}
]
I'm essentially looking to match on multiple specified keys that all these objects share, and take the remaining unspecified keys and combine them into a list, thus removing some duplicate information.
I'm using underscore.js, but I cannot find an example of this problem in the docs. Thanks in advance!
Sorry this doesn't conform with your revised requirements for a function but I got started before you revised and put in a lot of effort and I hope this is enough for you to put together your own function. Using underscore's _.reduce and _.each methods in succession (and the _.each can probably be replaced with a second _.reduce, or with _.map -- as usual there's more than one way to do it).
var arr = [
{ name: 'john', state: 'ny', age: 12}
, { name: 'john', state: 'ny', age: 22}
, { name: 'john', state: 'dc', age: 32}
, { name: 'john', state: 'dc', age: 42}
, { name: 'paul', state: 'ca', age: 52}
];
var resultsMap = _.reduce(arr, function(memo, arrEl) {
/*
* var key = JSON.stringify(_.omit(arrEl, 'age'));
*
* From original answer but naively fails to account for Javascript objects not returning in order.
* See "IIFE" below and http://stackoverflow.com/a/28989092/34806
*/
var key = (function() {
var ageOmittedObj = _.omit(arrEl, 'age');
var ageOmittedPairs = _.pairs(ageOmittedObj);
var sortedPairs = _.reduce(_.keys(ageOmittedObj).sort(), function(sortedPairs, key) {
var pair = _.find(ageOmittedPairs, function(kvPair) {return kvPair[0] == key});
sortedPairs.push(pair);
return sortedPairs;
}, []);
return JSON.stringify(sortedPairs)
}) ();
memo[key] = memo[key] || {};
memo[key].ages = memo[key].ages || [];
memo[key].ages.push(arrEl.age);
return memo;
}, {});
var resultsArr = [];
_.each(resultsMap, function(v, k) {
var resultObj = {};
var nameStatePairs = JSON.parse(k);
var nameStateObj = _.object(_.map(nameStatePairs, function(pair){return [pair[0], pair[1]]}));
// compare above to http://stackoverflow.com/a/17802471/34806
resultObj.name = nameStateObj.name;
resultObj.state = nameStateObj.state;
resultObj.age = v.ages;
resultsArr.push(resultObj);
});
console.log(JSON.stringify(resultsArr));
// [{"name":"john","state":"ny","age":[12,22]},{"name":"john","state":"dc","age":[32,42]},{"name":"paul","state":"ca","age":[52]}]
Not in underscore.js, but plain JS. Which should work fine since underscore is a library running on JavaScript.
I would output a new array using array.prototype.map combined with a for loop that test the new array for multiples. Since this is only one dimension deep, we do not need recursion.
var arr = [
{ name: "john", state: "ny", age: 12}
, { name: "john", state: "ny", age: 22}
, { name: "john", state: "dc", age: 32}
, { name: "john", state: "dc", age: 42}
, { name: "paul", state: "ca", age: 52}
]
var arr2d2 = []; //new array that is going to contain the merged values.
arr.map(function(element){
var outerElement = element;
var found = false; //set initially to false. If not found add element to the new array.
for (var i = 0; i < arr2d2.length; i++)
{
if (arr2d2[i].name == outerElement.name && arr2d2[i].state == outerElement.state)
{
found = arr2d2[i]; // save the element.
break; //stop the loop
}
};
if (found)
{
if (found.age != outerElement.age)
{
found.age.push(outerElement.age); //push the age to the new value.
}
}
else
{
outerElement.age = [outerElement.age]; //convert age to an array, like you specified.
arr2d2.push(outerElement); //not found yet. push element;
}
});
document.body.innerHTML += JSON.stringify(arr2d2); //only to display the result. Not part of the solution.

Categories