Related
I am trying to get the values from an array and assign to an array of objects as a new property.
The array of objects:
const employees = [
{
firstName: "Ana",
lastName: "Rosy"
},
{
firstName: "Zion",
lastName: "Albert"
},
{
firstName: "John",
lastName: "Doe"
}
];
An array
const ages = [30, 60, 45]
Desired result
const employees = [
{
firstName: "Ana",
lastName: "Rosy",
age:30
},
{
firstName: "Zion",
lastName: "Albert",
age:60
},
{
firstName: "John",
lastName: "Doe",
age:45
}
];
I tried something like this
const employeesWithAge = (ages) => {
return employees.map((row) => {
return {
...row,
age: ages
};
});
};
const result = employeesWithAge(ages);
console.log("result", result);
But it adds the entire array of ages to the employees array of objects.
Any help will be appreciated
You can use Array.prototype.map() for this. Use the spread syntax (...) on the current element to copy the properties into a new object, then add the age property based on the ages array, using .map() callback's second parameter (the current index).
employees.map((employee, i) => ({...employee, age: ages[i]}));
Live example:
const employees = [{
firstName: "Ana",
lastName: "Rosy"
},
{
firstName: "Zion",
lastName: "Albert"
},
{
firstName: "John",
lastName: "Doe"
}
];
const ages = [30, 60, 45];
const result = employees.map((employee, i) => ({ ...employee, age: ages[i] }));
console.log(result);
I think a simple for loop should solve your problem.
for (let i = 0; i < employees.length; i++) {
employees[i]["age"] = ages[i];
}
This loop iterates through the length of your list of employee objects and adds a new "age" attribute to each object with the corresponding age in your ages array.
All together I imagine your code looking something like this.
const employees = [
{
firstName: "Ana",
lastName: "Rosy"
},
{
firstName: "Zion",
lastName: "Albert"
},
{
firstName: "John",
lastName: "Doe"
}
];
const ages = [30, 60, 45];
for (let i = 0; i < employees.length; i++) {
employees[i]["age"] = ages[i];
}
console.log(employees);
I am trying to merge the two arrays based on Arr1 values. If the array 2 doesn't has the respective value in array1, it should return as empty object with values. Below are the two arrays:
Arr1 = [{
name: "raj",
age: 20
}, {
name: "ravi",
age: 40
}];
Arr2 = ['raj', 'ravi', 'arnold'];
Javascript Code is,
let result = Arr1.filter(o1 => Arr2.some(o2 => o2 === o1.name));
I am getting the result as below,
result = [{
name: "raj",
age: 20
}, {
name: "ravi",
age: 40
}];
But expected array should be,
[{
name: "raj",
age: 20
}, {
name: "ravi",
age: 40
}, {
name: "arnold",
age: null,
available: no
}];
Any suggestions?
You can use Array#map along with Array#find to obtain your expected result.
let Arr1 = [{
name: "raj",
age: 20
}, {
name: "ravi",
age: 40
}];
let Arr2 = ['raj', 'ravi', 'arnold'];
let result = Arr2.map(x=>
Arr1.find(({name})=>name===x)??{name:x,age:null,available: 'no'}
);
console.log(result);
I suggest a different approach and take an object for the given data and map the wanted names for eithe the given data or a new object.
This approach has a better big O, becaus it take a hash table and works fast for great data.
const
array1 = [{ name: "raj", age: 20 }, { name: "ravi", age: 40 }],
array2 = ['raj', 'ravi', 'arnold'],
data = array1.reduce((r, o) => (r[o.name] = o, r), {}),
result = array2.map(name => data[name] || { name, age: null, available: 'no' });
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
I have a working function that merges two arrays of objects by property a1 and a1. The solution was based on answers to some similar questions, however my requirement is to keep only the properties in the original array a1.
How can I adjust this function to return an array of objects containing only the properties in the first array?
Here is a JS fiddle with example data. Note that the output is logged to the console. Also note that the solution must be in vanilla Javascript ES6.
https://jsfiddle.net/dba9r3sf/
const a1 = [
{
FirstName: "John",
LastName: "Doe",
Age: 33,
Username: "jdoe"
},
{
FirstName: "Mary",
LastName: "Bloom",
Age: 63,
Username: "mbloom"
},
{
FirstName: "Alex",
LastName: "Arias",
Age: 21,
Username: "aarias"
}
];
const a2 = [
{
FirstName: "Johnathan",
LastName: "Doe",
Age: 34,
Username: "jdoe",
Job: "Graphic Designer"
},
{
FirstName: "Mary-Anne",
LastName: "Bloom",
Age: 64,
Username: "mbloom",
Job: "Investor"
},
{
FirstName: "Alex",
LastName: "Arias",
Age: 22,
Username: "aarias",
Job: "Student"
}
];
/**
* Merge an array of objects by property
* #param {array} a1 array 1 destination to be merged into
* #param {array} a2 array 2 source to be merged, overwrites existing values in a1
* #param {string} prop name of property to match for merge
* TODO: Set properties that exist on a1 only otherwise ignore
*/
function mergeByProperty(a1, a2, prop) {
let merged = [];
for (let i = 0; i < a1.length; i++) {
merged.push({
...a1[i],
...(a2.find((itmInner) => itmInner[prop] === a1[i][prop]))
});
}
return merged;
}
let result = mergeByProperty(a1, a2, 'Username');
console.log(JSON.stringify(result));
// Output:
[{"FirstName":"Johnathan","LastName":"Doe","Age":34,"Username":"jdoe","Job":"Graphic Designer"},{"FirstName":"Mary-Anne","LastName":"Bloom","Age":64,"Username":"mbloom","Job":"Investor"},{"FirstName":"Alex","LastName":"Arias","Age":22,"Username":"aarias","Job":"Student"}]
// Desired output (no "Job" property because that does not exist in the first array of objects):
[{"FirstName":"Johnathan","LastName":"Doe","Age":34,"Username":"jdoe"},{"FirstName":"Mary-Anne","LastName":"Bloom","Age":64,"Username":"mbloom},{"FirstName":"Alex","LastName":"Arias","Age":22,"Username":"aarias"}]
You can take keys form first array and then select corresponding key/value pair form second array
const a1 = [{FirstName: "John",LastName: "Doe",Age: 33,Username: "jdoe"},{FirstName: "Mary",LastName: "Bloom",Age: 63,Username: "mbloom"},{FirstName: "Alex",LastName: "Arias",Age: 21,Username: "aarias"}];
const a2 = [{FirstName: "Johnathan",LastName: "Doe",Age: 34,Username: "jdoe",Job: "Graphic Designer"},{FirstName: "Mary-Anne",LastName: "Bloom",Age: 64,Username: "mbloom",Job: "Investor"},{FirstName: "Alex",LastName: "Arias",Age: 22,Username: "aarias",Job: "Student"}];
function mergeByProperty(a1, a2, prop) {
let merged = [];
for (let i = 0; i < a1.length; i++) {
let found = a2.find((itmInner) => itmInner[prop] === a1[i][prop])
if(found){
found = Object.keys(a1[0]).reduce((op,inp)=>{
op[inp] = found[inp]
return op
},{})
}
merged.push({
...a1[i],
...found
});
}
return merged;
}
let result = mergeByProperty(a1, a2, 'Username');
console.log((result));
You can create a username map from a2 then simply Array.map over the a1 array and merge with a custom merge function which does nothing more than Array.reduce over the keys of a1 and assigns the values from a2:
const a1 = [ { FirstName: "John", LastName: "Doe", Age: 33, Username: "jdoe" }, { FirstName: "Mary", LastName: "Bloom", Age: 63, Username: "mbloom" }, { FirstName: "Alex", LastName: "Arias", Age: 21, Username: "aarias" } ];
const a2 = [ { FirstName: "Johnathan", LastName: "Doe", Age: 34, Username: "jdoe", Job: "Graphic Designer" }, { FirstName: "Mary-Anne", LastName: "Bloom", Age: 64, Username: "mbloom", Job: "Investor" }, { FirstName: "Alex", LastName: "Arias", Age: 22, Username: "aarias", Job: "Student" } ];
let obj = a2.reduce((r,c) => (r[c.Username] = c, r), {}) // username map
let merge = (a, b, props) => props.reduce((r,c) => (r[c] = b[c], r), a)
let result = a1.map(x => merge(x, obj[x.Username], Object.keys(x)))
console.log(result)
You can do something like this:
const a1 = [
{
FirstName: "John",
LastName: "Doe",
Age: 33,
Username: "jdoe"
},
{
FirstName: "Mary",
LastName: "Bloom",
Age: 63,
Username: "mbloom"
},
{
FirstName: "Alex",
LastName: "Arias",
Age: 21,
Username: "aarias"
}
];
const a2 = [
{
FirstName: "Johnathan",
LastName: "Doe",
Age: 34,
Username: "jdoe",
Job: "Graphic Designer"
},
{
FirstName: "Mary-Anne",
LastName: "Bloom",
Age: 64,
Username: "mbloom",
Job: "Investor"
},
{
FirstName: "Alex",
LastName: "Arias",
Age: 22,
Username: "aarias",
Job: "Student"
}
];
const result = a1.map((obj1, index) => {
const obj2 = a2[index];
if (obj2) {
return Object.keys(obj1).reduce((acc, key) => {
acc[key] = obj2[key];
return acc;
}, {});
}
return obj1;
}, []);
console.log(result);
We have an array of objects like:
const persons = [{
name: "john",
age: 23
}, {
name: "lisa",
age: 43
}, {
name: "jim",
age: 101
}, {
name: "bob",
age: 67
}];
And an array of a attribute values of the objects in object
const names = ["lisa", "bob"]
How can we find persons with name in the names array using es6, like:
const filteredPersons = [{
name: "lisa",
age: 43
}, {
name: "bob",
age: 67
}];
ES6
Use filter function with predicate and in it check the existence of the name in the names array.
const persons = [
{name: "john", age:23},
{name: "lisa", age:43},
{name: "jim", age:101},
{name: "bob", age:67}
];
const names = ["lisa", "bob"];
const filtered = persons.filter(person => names.includes(person.name));
console.log(filtered);
You can use filter() and inlcudes() to get required result.
DEMO
const persons = [{
name: "john",
age: 23
}, {
name: "lisa",
age: 43
}, {
name: "jim",
age: 101
}, {
name: "bob",
age: 67
}];
const names = ["lisa", "bob"];
console.log(persons.filter(({
name
}) => names.includes(name)))
.as-console-wrapper { max-height: 100% !important; top: 0; }
I would suggest to use indexOf as includes does not work in IE browser. Also, using {name} works as Destructuring assignment that will hold the value of name property of the object.
const persons = [{
name: "john",
age: 23
}, {
name: "lisa",
age: 43
}, {
name: "jim",
age: 101
}, {
name: "bob",
age: 67
}];
const names = ["lisa", "bob"];
console.log(persons.filter(({name}) => names.indexOf(name) !== -1))
lodash
You can try following
const persons = [{name: "john", age: 23},
{name: "lisa",age: 43},
{name: "jim", age: 101},
{name: "bob",age: 67}];
const names = ["lisa", "bob"]
const filteredPersons = _.filter(persons, function(person) {
return _.indexOf(names, person.name) !== -1;
});
console.log(filteredPersons);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/3.10.1/lodash.js"></script>
In case you want to perform it in n complexity, here is a way to do it:
Create a map with key as person's name and value as person's object.
Map the criteria array and extract the person objects from the map create in step 1.
Here is a working demo:
const persons = [{
name: "john",
age: 23
}, {
name: "lisa",
age: 43
}, {
name: "jim",
age: 101
}, {
name: "bob",
age: 67
}];
const names = ["lisa", "bob"];
const map = persons.reduce((acc, item) => {
acc[item.name] = item;
return acc;
}, {});
const result = names.map(name => map[name]);
console.log(result);
Note: This solution assumes that only unique person names are in the source array. It needs to be tweaked to handle duplicates.
See Closures, Set, and Array.prototype.filter() for more info.
// Input.
const persons = [{name: "john",age: 23}, {name: "lisa",age: 43}, {name: "jim",age: 101}, {name: "bob",age: 67}]
const names = ["lisa", "bob"]
// Filter.
const filter = (A, B) => (s => A.filter(x => s.has(x.name)))(new Set(B))
// Output.
const output = filter(persons, names)
// Proof.
console.log(output)
I have an object:
person = {
birth_year: 1970,
first_name: "John",
last_name: "Doe",
occupation: "Doctor",
city: "Boston",
married: true
}
I have an array of key names in given order:
keys = ["occupation", "last_name", "city"]
I want to get this array:
["Doctor", "Doe", "Boston"]
It is important, that the answer should guarantee the order (JavaScript does not guarantee the order for object iteration).
I think there is probably some utility function in lodash/underscore to do it simply, but can't figure out any.
You can use Array.prototype.map for this. Map loops through an array and creates a new array by applying a function to each item. When you use the keys array as a starting point, and return the value in o for that key, you'll get a new array with only values.
When using "dynamic" key names, you use a object[stringKeyName] notation to retrieve a value.
var o = {
birth_year: 1970,
first_name: "John",
last_name: "Doe",
occupation: "Doctor",
city: "Boston",
married: true
};
var keys = ["occupation", "last_name", "city"];
var result = keys.map(function(k) { return o[k]; });
console.log(result);
If it fits your style, you can create a helper method to replace the anonymous function:
var o = { birth_year: 1970, first_name: "John", last_name: "Doe", occupation: "Doctor", city: "Boston", married: true };
var keys = ["occupation", "last_name", "city"];
var prop = obj => key => obj[key];
var result = keys.map(prop(o));
console.log(result);
With Lodash you could use pick and values
var o = {
birth_year: 1970,
first_name: "John",
last_name: "Doe",
occupation: "Doctor",
city: "Boston",
married: true
}
var keys = ["occupation", "last_name", "city"];
var result = _.values(_.pick(o, keys));
console.log(result)
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.15.0/lodash.min.js"></script>