Hi guys and sorry for my english. I have this array of objects and I need to get an input like:
{name: Karen, age: 12} -> Karen-12.
How can I do it?
This is the exercise:
function nicknameMap(p) {
}
const p = [
{ name: 'ninny', age: 19},
{ name: 'albert', age: 20},
{ name: 'daniel', age: 60},
{ name: 'bob', age: 20},
{ name: 'wilfred', age: 40},
{ name: 'rob', age: 22},
{ name: 'gary', age: 9},
{ name: 'robin', age: 19},
{ name: 'carl', age: 43 },
{ name: 'v', age: 82 }
];
const nicknames = nicknameMap(p);
console.log(p);
console.log(nicknames);```
Use the .map() array method as follows:
function nicknameMap(p) {
return p.map(({name,age}) => `${name}-${age}`);
}
//output
//[
// "ninny-19",
// "albert-20",
// "daniel-60",
// "bob-20",
// .....
//]
function nicknameMap(p) {
return p.map(({name,age}) => `${name}-${age}`);
}
const p = [
{ name: 'ninny', age: 19},
{ name: 'albert', age: 20},
{ name: 'daniel', age: 60},
{ name: 'bob', age: 20},
{ name: 'wilfred', age: 40},
{ name: 'rob', age: 22},
{ name: 'gary', age: 9},
{ name: 'robin', age: 19},
{ name: 'carl', age: 43 },
{ name: 'v', age: 82 }
];
const nicknames = nicknameMap(p);
console.log(p);
console.log(nicknames);
function nicknameMap(p) {
let result = Array();
p.forEach((n) => {
result.push(`${n.name}-${n.age}`);
});
return result;
}
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/push
It's best to learn by yourself, but I'm assuming you've had a crack at it and are asking because you have run out of options.
EDIT: amlxv solution is a more "Javascript" way of doing it, and is technically more correct than mine.
Below is a solution to your problem.
function nicknameMap(p) {
let arr = [];
for(let i = 0; i<p.length; i++){
arr.push(p[i].name + "-" + p[i].age);
}
return arr;
}
const p = [
{ name: 'ninny', age: 19},
{ name: 'albert', age: 20},
{ name: 'daniel', age: 60},
{ name: 'bob', age: 20},
{ name: 'wilfred', age: 40},
{ name: 'rob', age: 22},
{ name: 'gary', age: 9},
{ name: 'robin', age: 19},
{ name: 'carl', age: 43 },
{ name: 'v', age: 82 }
];
const nicknames = nicknameMap(p);
console.log(p);
console.log(nicknames);
Related
What is wrong in this if condition. I am getting the wrong result. I need to get equal values in these two objects and diff between them.
const firstArr = [{ name: 'tom', age: 22, city: 'Madrid' }, { name: 'Alex', age: 23, city: 'Berlin' }, { name: 'Sara', age: 28, city: 'Paris' }, { name: 'Rash', age: 20, city: 'Dubai' } ];
const secondArr = [{ name: 'tom', age: 22, city: 'Madrid' }, { name: 'Alex', age: 27, city: 'Berlin' }, { name: 'Hary', age: 29, city: 'London' }, ];
for (let i = 0; i < firstArr.length; i++) {
for (let j = 0; j < secondArr.length; j++) {
if (firstArr[i].name == secondArr[j].name) {
console.log('eq', firstArr[i].city, secondArr[j].city)
}
if (firstArr[i].name != secondArr[j].name) {
console.log('not found in second array', firstArr[i].city)
}
if (secondArr[j].name != firstArr[i].name) {
console.log('not found in first array', secondArr[j].city)
}
}
}
Currently you compare each element of the first array with each element of the second array. You could instead use Array.prototype.some and Array.prototype.every to filter the arrays and to find the intersection resp. difference. Then you can map the objects to the city names.
const firstArr = [{ name: 'tom', age: 22, city: 'Madrid' }, { name: 'Alex', age: 23, city: 'Berlin' }, { name: 'Sara', age: 28, city: 'Paris' }, { name: 'Rash', age: 20, city: 'Dubai' } ];
const secondArr = [{ name: 'tom', age: 22, city: 'Madrid' }, { name: 'Alex', age: 27, city: 'Berlin' }, { name: 'Hary', age: 29, city: 'London' }, ];
function intersect(lhs, rhs) {
return lhs.filter(el => rhs.some(el2 => el.name === el2.name)).map(el => el.city);
}
function diff(lhs, rhs) {
return lhs.filter(el => rhs.every(el2 => el.name !== el2.name)).map(el => el.city);
}
console.log(intersect(firstArr, secondArr));
console.log(diff(firstArr, secondArr));
console.log(diff(secondArr, firstArr));
I loop the first array first and find matches in second array. If there is a match, diff is displayed. If there is no such match, then the correct text is being displayed. An array is built along the way, which is used to simplify the loop on the second array.
const firstArr = [{ name: 'tom', age: 22, city: 'Madrid' }, { name: 'Alex', age: 23, city: 'Berlin' }, { name: 'Sara', age: 28, city: 'Paris' }, { name: 'Rash', age: 20, city: 'Dubai' } ];
const secondArr = [{ name: 'tom', age: 22, city: 'Madrid' }, { name: 'Alex', age: 27, city: 'Berlin' }, { name: 'Hary', age: 29, city: 'London' }, ];
let names = [];
for (let first of firstArr) {
let matches = secondArr.filter((second) => (first.name === second.name));
if (matches.length) {
console.log('eq', first.city, matches[0].city)
} else {
console.log('not found in second array', first.city);
}
names.push(first.name);
}
for (let second of secondArr) {
if (names.indexOf(second.name) === -1) console.log('not found in first array', second.city);
}
Try this:
const firstArr = [{ name: 'tom', age: 22, city: 'Madrid' }, { name: 'Alex', age: 23, city: 'Berlin' }, { name: 'Sara', age: 28, city: 'Paris' }, { name: 'Rash', age: 20, city: 'Dubai' } ];
const secondArr = [{ name: 'tom', age: 22, city: 'Madrid' }, { name: 'Alex', age: 27, city: 'Berlin' }, { name: 'Hary', age: 29, city: 'London' }, ];
var eq = [], uniqueInFirst = [], uniqueInSecond = [];
for (let i = 0; i < firstArr.length; i++) {
var secondArrCities = Object.values(secondArr).map ((obj) => {return obj.city})
if (secondArrCities.includes(firstArr[i].city)) {
eq.push(firstArr[i].city)
} else {
uniqueInFirst.push(firstArr[i].city)
}
}
for (let i = 0; i < secondArr.length; i++) {
var firstArrCities = Object.values(firstArr).map ((obj) => {return obj.city})
if (!firstArrCities.includes(secondArr[i].city)) {
uniqueInSecond.push(secondArr[i].city)
}
}
console.log(eq)
console.log(uniqueInFirst)
console.log(uniqueInSecond)
I have an array of json elements. and I want to filter the array based on the specific values. below is the array.
var arr = [
{name: bobby, id: 1, age: 23},
{name: charls, id: 2, age: 28},
{name: indi, id: 3, age: 23},
{name: charlie, id: 4, age: 25}]
from the above array I want to filter only staff whose names are bobby && indi. I have tried below code.
var filteredArray;
for (var i =0 ; i < arr.length; i++){
if(arr[i].name === 'bobby' || arr[i].name === 'indi'){
filteredArray.push(arr[i]);
}
}
but through the above code, I need to mention OR(||) conditions too many times and these number of names can change like 1 time I want only staff with Bobby name and other time I want Bobby, Indi and Charlie. is there a way to make it dynamic. if yes, please let me know. Thanks in advance.
You can store names that needs to be filters in an array and then check if name exists in array or not
eg.
var arr = [
{name: "bobby", id: 1, age: 23},
{name: "charls", id: 2, age: 28},
{name: "indi", id: 3, age: 23},
{name: "charlie", id: 4, age: 25}
]
const names = ["bobby", "indi"];
const filtered = arr.filter((item)=>{
return names.includes(item.name)
});
console.log(filtered)
For older(eg. IE11) browsers -
var arr = [
{name: "bobby", id: 1, age: 23},
{name: "charls", id: 2, age: 28},
{name: "indi", id: 3, age: 23},
{name: "charlie", id: 4, age: 25}
]
const names = ["bobby", "indi"];
const filtered = [];
for(var i =0; i<arr.length - 1; i++){
if(names.indexOf(arr[i].name) > -1){
filtered.push(arr[i])
}
}
console.log(filtered)
You can use Array.includes() to filter items as followings:
var arr = [
{name: 'bobby', id: 1, age: 23},
{name: 'charls', id: 2, age: 28},
{name: 'indi', id: 3, age: 23},
{name: 'charlie', id: 4, age: 25}
]
const keywords = ['bobby', 'indi'] // You can add keywords to be filtered to this array to make it dynamic
const filtered = arr.filter(item => keywords.includes(item.name))
console.log(filtered)
You could create an array of names you want to filter and then:
if you want to stick to pre-ES6 coding:
var arr = [{
name: 'bobby',
id: 1,
age: 23
},
{
name: 'charls',
id: 2,
age: 28
},
{
name: 'indi',
id: 3,
age: 23
},
{
name: 'charlie',
id: 4,
age: 25
}
];
var names = ['bobby', 'indi'];
var filteredArray = [];
for (var i = 0; i < arr.length; i++) {
if (names.indexOf(arr[i].name) > -1) filteredArray.push(arr[i]);
}
console.log(filteredArray);
or, if you are willing to switch to ES6+ coding:
const arr = [{
name: 'bobby',
id: 1,
age: 23
},
{
name: 'charls',
id: 2,
age: 28
},
{
name: 'indi',
id: 3,
age: 23
},
{
name: 'charlie',
id: 4,
age: 25
}
];
const names = ['bobby', 'indi'];
const filteredArray = arr.filter(item => names.includes(item.name));
console.log(filteredArray);
I've 2 arrays with partial information and I wish to merge those arrays with all the information into one array.
Array 1 :
const arr1 = [
{
name: 'Rohan',
surname: 'Mehra',
age: '15',
date: "2021-01-19",
location: 'Goa'
},
{
name: 'Aman',
surname: 'Kohli',
age: '14',
date: "2021-01-19",
location: 'Kolkata'
},
{
name: 'Sam',
surname: 'Sharma',
age: '16',
date: "2021-01-21",
location: 'Mumbai'
}
]
Array 2 :
const arr2 = [
{
rollNo: 1,
marks: 100,
name: 'Rohan',
date: "2021-01-19",
},
{
rollNo: 2,
marks: 90,
surname: 'Kohli',
date: "2021-01-19",
},
{
rollNo: 3,
marks: 70,
date: "2021-01-21",
ExamCenter: {
place: 'Mumbai'
}
}
]
I want to get a final array with the properties from both arrays. The Object keys sometimes change and I wanted to match the key with the other common key and merge them. But I am not able to proceed with the solution. Here is the result array I wish to get.
const final = [
{
name: 'Rohan',
surname: 'Mehra',
age: '15',
date: "2021-01-19",
location: 'Goa',
rollNo: 1,
marks: 100,
},
{
name: 'Aman',
surname: 'Kohli',
age: '14',
date: "2021-01-19",
location: 'Kolkata',
rollNo: 2,
marks: 90,
},
{
name: 'Sam',
surname: 'Sharma',
age: '16',
date: "2021-01-21",
location: 'Mumbai',
rollNo: 3,
marks: 70,
}
]
I'm trying with nested map loops but not able to proceed
const final = arr1.map((item,index) => {
arr2.map((innerItem, i) => {
if(item[Object.keys(innerItem)][index] === innerItem[Object.keys(innerItem)][0]){
console.log(item);
}
})
})
There is a mistake in your arr2. The surname for 2nd item should be kohli instead of kolhi. Anyway, You can do the following to merge two array based on dynamic matching attribute. What we are doing here is,
For each item of arr1 we are finding the keys using Object.keys method and checking which object from arr2 has maximum matching object with the item of arr1. Then we merge the two item together.
arr1 = [
{
name: 'Rohan',
surname: 'Mehra',
age: '15',
date: "2021-01-19",
location: 'Goa'
},
{
name: 'Aman',
surname: 'Kohli',
age: '14',
date: "2021-01-19",
location: 'Kolkata'
},
{
name: 'Sam',
surname: 'Sharma',
age: '16',
date: "2021-01-21",
location: 'Mumbai'
}
]
arr2 = [
{
rollNo: 1,
marks: 100,
name: 'Rohan',
date: "2021-01-19",
},
{
rollNo: 2,
marks: 90,
surname: 'Kohli',
date: "2021-01-19",
},
{
rollNo: 3,
marks: 70,
date: "2021-01-21",
ExamCenter: {
place: 'Mumbai'
}
}
]
res = arr1.map(item => {
keys1 = Object.keys(item);
let max = 0;
const temp = arr2.reduce((prev, item2) => {
maxTemp = keys1.filter(key => item[key] === item2[key]).length;
if(maxTemp > max) {
max = maxTemp;
prev = item2;
}
return prev;
}, {})
if(temp) {
return {...item, ...temp}
}
});
console.log(res);
You can do something like this to merge two arrays.
const arr1 = [
{
name: 'Rohan',
surname: 'Mehra',
age: '15',
date: "2021-01-19",
location: 'Goa'
},
{
name: 'Aman',
surname: 'Kohli',
age: '14',
date: "2021-01-19",
location: 'Kolkata'
},
{
name: 'Sam',
surname: 'Sharma',
age: '16',
date: "2021-01-21",
location: 'Mumbai'
}
]
const arr2 = [
{
rollNo: 1,
marks: 100,
name: 'Rohan',
date: "2021-01-19",
},
{
rollNo: 2,
marks: 90,
surname: 'Kolhi',
date: "2021-01-19",
},
{
rollNo: 3,
marks: 70,
date: "2021-01-21",
ExamCenter: {
place: 'Mumbai'
}
}
]
const newArray = [];
arr2.forEach((item) => {
const array1Item = arr1.find(({ date }) => date === item.date);
if (array1Item) {
newArray.push({
...item,
...array1Item,
})
}
})
console.log(newArray);
This may help you
const arr3 = arr1.map((value, index) => {
return Object.assign(value, arr2[index])
})
I have an array of objects, I need to group them by the same value, I need to group them by a multidimensional array
const source = [
{name: 'A', age: 23, id: 0},
{name: 'A', age: 23, id: 1},
{name: 'B', age: 15, id: 34},
{name: 'B', age: 15, id: 45},
{name: 'B', age: 15, id: 32},
{name: 'C', age: 15, id: 32},
];
[
Like this structure, all the same objects should be grouped by array inside an array.
[
{name: 'A', age: 23, id: 0},
{name: 'A', age: 23, id: 1}
],
[
{name: 'B', age: 15, id: 34},
{name: 'B', age: 15, id: 45},
{name: 'B', age: 15, id: 32}
],
[
{name: 'C', age: 15, id: 32},
]
]
I have tried like this but no luck.
const result = source.reduce((accumulator, item) => {
if (accumulator && accumulator.length) {
const found = accumulator.find(group => {
return group && group.length
? group.find(_transaction =>
// check the same object
return false
)
: false;
});
if (found) {
console.log(found);
}
} else {
accumulator.push([item]);
}
return accumulator;
}, []);
Create an object indexed by the name property, whose values are arrays containing the source items, then take the object's values:
const source = [
{name: 'A', age: 23, id: 0},
{name: 'A', age: 23, id: 1},
{name: 'B', age: 15, id: 34},
{name: 'B', age: 15, id: 45},
{name: 'B', age: 15, id: 32},
{name: 'C', age: 15, id: 32},
];
const sourceItemsByName = {};
for (const obj of source) {
if (!sourceItemsByName[obj.name]) {
sourceItemsByName[obj.name] = [];
}
sourceItemsByName[obj.name].push(obj);
}
const output = Object.values(sourceItemsByName);
console.log(output);
You can reduce the array to a Map, using the name and age combination as the key. Then spread the Map.values() iterator back to an array:
const source = [{ name: 'A', age: 23, id: 0 }, { name: 'A', age: 23, id: 1 }, { name: 'B', age: 15, id: 34 }, { name: 'B', age: 15, id: 45 }, { name: 'B', age: 15, id: 32 }, { name: 'C', age: 15, id: 32 }];
const result = [... // spread the values iterator to an array
source.reduce((r, o) => {
const key = `${o.name}---${o.age}`; // generate a key with name and age
if(!r.has(key)) r.set(key, []); // add a new entry for key if it's not in the Map
r.get(key).push(o); // push the current object to the keys's entry
return r;
}, new Map())
.values() // get the Maps values iterator
];
console.log(result);
I think the following code is easier to understand. Hope, it will help you. Thanks.
UPDATED: As you need mentioned in a comment that you need name and age property as your key value.
const source = [
{name: 'A', age: 23, id: 0},
{name: 'A', age: 23, id: 1},
{name: 'B', age: 15, id: 34},
{name: 'B', age: 15, id: 45},
{name: 'B', age: 15, id: 32},
{name: 'C', age: 15, id: 32},
];
var hashObject = {}
source.forEach(function(elem) {
var key = elem.name + elem.age;
if (hashObject[key]) {
hashObject[key].push(elem);
} else {
hashObject[key] = [elem];
}
});
var desiredArray = Object.values(hashObject);
console.log(desiredArray);
You could find the group array and if found add the object or add a new group to the result set.
const
source = [{ name: 'A', age: 23, id: 0 }, { name: 'A', age: 23, id: 1 }, { name: 'B', age: 15, id: 34 }, { name: 'B', age: 15, id: 45 }, { name: 'B', age: 15, id: 32 }, { name: 'C', age: 15, id: 32 }],
groups = ['name', 'age'],
grouped = source.reduce((r, o) => {
var temp = r.find(([q]) => groups.every(k => o[k] === q[k]));
if (temp) {
temp.push(o);
} else {
r.push([o]);
}
return r;
}, []);
console.log(grouped);
.as-console-wrapper { max-height: 100% !important; top: 0; }
An approach with a Map
const
source = [{ name: 'A', age: 23, id: 0 }, { name: 'A', age: 23, id: 1 }, { name: 'B', age: 15, id: 34 }, { name: 'B', age: 15, id: 45 }, { name: 'B', age: 15, id: 32 }, { name: 'C', age: 15, id: 32 }],
groups = ['name', 'age'],
grouped = Array.from(source
.reduce(
(m, o) =>
(k => m.set(k, [...(m.get(k) || []), o]))
(groups.map(k => o[k]).join('|')),
new Map)
.values()
);
console.log(grouped);
.as-console-wrapper { max-height: 100% !important; top: 0; }
I would like to compare a property of an object of two arrays of different lengths. If my condition is true (gender check) and then if that property matches then I would like to combine the properties of that object from both arrays and store it in a different array.
For example:
// array 1
var array1 = [{name: 'Jan', age: 19, category: {gender: 'Male'}}, {name: 'Suzy', age: 29, category: {gender: 'Female'}}, {name: 'Peter', age: 39, category: {gender: 'Male'}}, {name: 'Bart', age: 49, category: {gender: 'Male'}}, {name: 'John', age: 59, category: {gender: 'Male'}}];
// array 2
var array2 = [{name:'Kean', job: 'Technician'},{name:'Nick', job:'Mathematics'},{name: 'Jan', job: 'Tester'}, {name: 'Suzy', job:'Developer'}, {name: 'Peter', job: 'Scrum master'}]
Expected result:
var resultMale = [{name: 'Jan', age: 19,job: 'Tester'}, {name: 'Peter', age: 39, job: 'Scrum master'}];
var resultFemale = [{name: 'Suzy', age: 29, job:'Developer'}];
Below is my attempt just to show that I have been putting all my effort to find a solution myself. I have changed all the functions and variable names
this.
xxxxxxxx.getContractsForRules().then(res => {
// res.xxxxxx.forEach(function (obj) {
// if(obj.contract.product.xxxxxxx=== 'xxxxxxx') {
// console.log(this.xxxxxx.xx);
// for(let i=0; i < this.xxxxxxx.length; i++) {
// if(obj.contract.accountNumber === this.xxxxxxxx[i].ibanNumber) {
// this.currentAccount = {
// accountNumber: res.xxxxx[i].contract.accountNumber,
// accountName: res.xxxxx[i].contract.customer.xxxxxx
// };
// this.xxxxxxx.push(this.xxxxxx);
// }
// };
// }
// });
this.result = res.contractList.filter(item => this.allCurrentAccounts.);
if(res.xxxx[i].contract.xxxxx=== this.xxxxx[i].ibanNumber) {
this.savingAccount = {
accountNumber: xxxx.xxxx[i].contract.accountNumber,
accountName: res.xxxxx[i].contract.customer.xxxxx
};
this.xxxxx.push(this.xxxxx);
}
});
this.test();
}
What you finally need is an Intersection of both the arrays. So, you could do the following -
var array1 = [{ name: 'Jan', age: 19, category: { gender: 'Male' } }, { name: 'Suzy', age: 29, category: { gender: 'Female' } }, { name: 'Peter', age: 39, category: { gender: 'Male' } }, { name: 'Bart', age: 49, category: { gender: 'Male' } }, { name: 'John', age: 59, category: { gender: 'Male' } }];
var array2 = [{ name: 'Kean', job: 'Technician' }, { name: 'Nick', job: 'Mathematics' }, { name: 'Jan', job: 'Tester' }, { name: 'Suzy', job: 'Developer' }, { name: 'Peter', job: 'Scrum master' }];
// Empty arrays to contain final intersection array for both male & females
var resultMale = [], resultFemale = [];
/* now looping over both arrays to traverse all the elements from them */
// iterating over first array
array1.forEach(x => {
// iterating over second array
array2.forEach(y => {
// collect the objects only if the name attribute matches in both
if (x.name == y.name) {
// push into male array if gender is male else push into female array
if (x.category && x.category['gender'] == 'Male') {
resultMale.push({
name: x.name,
age: x.age,
job: y.job
});
} else if (x.category && x.category['gender'] == 'Female') {
resultFemale.push({
name: x.name,
age: x.age,
job: y.job
});
}
}
});
});
console.log(resultMale);
console.log(resultFemale);
Note - this can be optimized to reduce the time complexity.