I have given array of objects, something like this
const data = [
{id: 1, name: 'Alex', job: 'IT'},
{id: 2, name: 'Pavel', job: 'IT'},
{id: 3, name: 'Joe', job: 'IT'},
{id: 4, name: 'Josh', job: 'IT'},
{id: 5, name: 'Max', job: 'teacher'},
{id: 6, name: 'Sam', job: 'teacher'}
]
I need array of arrays filtered by field job
const result = [
{job: 'IT',
workersInfo: [
{id:1, name:'Alex'},
{id:2, name:'Pavel'},
{id:3, name:'Joe'},
{id:4, name:'Josh'}
]
},
{job: 'teacher',
workersInfo: [
{id:5, name: 'Max'},
{id:6, name: 'Sam'}
]
}
]
I tried this, but It's not what I want
const data = [
{id: 1, name: 'Alex', job: 'IT'},
{id: 2, name: 'Pavel', job: 'IT'},
{id: 3, name: 'Joe', job: 'IT'},
{id: 4, name: 'Josh', job: 'IT'},
{id: 5, name: 'Max', job: 'teacher'},
{id: 6, name: 'Sam', job: 'teacher'}
]
const groupList = data.reduce((reduce, it) => {
reduce[it.job] = reduce[it.job] || [];
reduce[it.job].push({id: it.id, name: it.name});
return reduce;
}, {})
console.log(Object.values(groupList));
How can I add new key workers Info and push info to this field
If you create a new object on each iteration instead of an array you can then use Object.values:
const data = [
{id: 1, name: 'Alex', job: 'IT'},
{id: 2, name: 'Pavel', job: 'IT'},
{id: 3, name: 'Joe', job: 'IT'},
{id: 4, name: 'Josh', job: 'IT'},
{id: 5, name: 'Max', job: 'teacher'},
{id: 6, name: 'Sam', job: 'teacher'}
];
const groupList = data.reduce((acc, { job, id, name }) => {
acc[job] = acc[job] || { job, workersInfo: [] };
acc[job].workersInfo.push({ id, name });
return acc;
}, {})
console.log(Object.values(groupList));
Example below
const data = [
{ id: 1, name: "Alex", job: "IT" },
{ id: 2, name: "Pavel", job: "IT" },
{ id: 3, name: "Joe", job: "IT" },
{ id: 4, name: "Josh", job: "IT" },
{ id: 5, name: "Max", job: "teacher" },
{ id: 6, name: "Sam", job: "teacher" },
];
const output = data.reduce((acc, o) => {
const index = acc.findIndex(a => a.job === o.job);
if (index !== -1) {
acc[index].workersInfo.push({ id: o.id, name: o.name });
} else {
acc.push({
job: o.job,
workersInfo: [{ id: o.id, name: o.name }],
});
}
return acc;
}, []);
console.log(output);
Would something like this work ?
const groupBy = function(xs, key) {
return xs.reduce(function(rv, x) {
(rv[x[key]] = rv[x[key]] || []).push(x);
return rv;
}, {});
};
console.log(groupBy(['one', 'two', 'three'], 'length'));
// => {3: ["one", "two"], 5: ["three"]}```
It would be more efficient and comprehensible if instead of having a structure like Array<{job: string, workForce: Array}>, you had something like {[job: string]: Array}
var data = [
{ id: 1, name: 'Alex', job: 'IT' },
{ id: 2, name: 'Pavel', job: 'IT' },
{ id: 3, name: 'Joe', job: 'IT' },
{ id: 4, name: 'Josh', job: 'IT' },
{ id: 5, name: 'Max', job: 'teacher' },
{ id: 6, name: 'Sam', job: 'teacher' }
];
var jobs = data.reduce(function (result, person) {
var jobList = result[person.job];
if (!jobList) {
jobList = [];
result[person.job] = jobList;
}
jobList.push(person);
return result;
}, {});
console.log(jobs);
Related
There is one scenario where i need to replace the existing records from cached data with new incoming data source. Looking for the cleaner approach to handle the array operations.
For example:
var userCategory = [
{
id: 'platinum',
name: 'bob',
},
{
id: 'platinum',
name: 'bar',
},
{
id: 'platinum',
name: 'foo',
},
{
id: 'gold',
name: 'tom',
},
{
id: 'silver',
name: 'billy',
},
];
Here is new users of particular category
var newPlatinumUsers = [
{
id: 'platinum',
name: 'bob',
},
{
id: 'platinum',
name: 'mike',
},
];
This is the expected result needed:
var expected = [
{
id: 'platinum',
name: 'bob',
},
{
id: 'platinum',
name: 'mike',
},
{
id: 'gold',
name: 'tom',
},
{
id: 'silver',
name: 'billy',
},
];
I tried with filtering all the platinum user from existing records then added the new records but it looks verbose
Is there any cleaner approach like lodash operator??
Thanks for your time!!!
May you are looking for this.
function getUnique(arr){
// removing duplicate
let uniqueArr = [...new Set(arr)];
document.write(uniqueArr);
}
const array = ['acer','HP','Apple','Apple','something'];
// calling the function
getUnique(array);
Verify my answer if it help you.
Please find the Javascript implementation of the same
var userCategory = [
{ id: 'platinum', name: 'bob', },
{ id: 'platinum', name: 'bar', },
{ id: 'platinum', name: 'foo', },
{ id: 'gold', name: 'tom', },
{ id: 'silver', name: 'billy', },
];
var newPlatinumUsers = [
{ id: 'platinum', name: 'bob', },
{ id: 'platinum', name: 'mike', },
];
const result = [...newPlatinumUsers];
userCategory.forEach((node) => {
if(node.id !== 'platinum') {
result.push(node);
}
});
console.log(result);
With this solution you can change more than one category:
var userCategory = [
{id: 'platinum',name: 'bob'},
{id: 'platinum',name: 'bar'},
{id: 'platinum',name: 'foo'},
{id: 'gold',name: 'tom'},
{id: 'silver',name: 'billy'},
];
var newUsers = [
{id: 'platinum',name: 'bob'},
{id: 'platinum',name: 'mike'},
{id: 'gold',name: 'will'},
{id: 'gold',name: 'jerry'},
];
const idsToReplace = {}
const result = [...newUsers]
result.forEach(u => {
idsToReplace[u.id] = true
})
userCategory.forEach(u => {
if(!idsToReplace[u.id]){
result.push(u)
}
})
console.log(result)
I have an array containing several hundred objects, each of which has a category. I wish to return an object that lists out the categories with a count of the number of items for each category.
const arr = [
{id: 1, name: 'ford', category: 'vehicle'},
{id: 2, name: 'pig', category: 'animal'},
{id: 3, name: 'dog', category: 'animal'},
{id: 4, name: 'chev', category: 'vehicle'},
{id: 5, name: 'cat', category: 'animal'},
{id: 6, name: 'jeep', category: 'vehicle'},
{id: 7, name: 'honda', category: 'vehicle'}
]
How would I loop through the object and create a new object that contains just the two categories and how many of each per category?
Desired output:
{vehicle: 4, animal: 3}
Code:
const arr = [
{id: 1, name: 'ford', category: 'vehicle'},
{id: 2, name: 'pig', category: 'animal'},
{id: 3, name: 'dog', category: 'animal'},
{id: 4, name: 'chev', category: 'vehicle'},
{id: 5, name: 'cat', category: 'animal'},
{id: 6, name: 'jeep', category: 'vehicle'},
{id: 7, name: 'honda', category: 'vehicle'}
]
const final = {};
arr.forEach((v) => {
const tst = v.category;
console.log(tst);
if (tst in final){
console.log('found one');
}
});
//console.log(final);
You can use reduce
const arr = [
{id: 1, name: 'ford', category: 'vehicle'},
{id: 2, name: 'pig', category: 'animal'},
{id: 3, name: 'dog', category: 'animal'},
{id: 4, name: 'chev', category: 'vehicle'},
{id: 5, name: 'cat', category: 'animal'},
{id: 6, name: 'jeep', category: 'vehicle'},
{id: 7, name: 'honda', category: 'vehicle'}
]
const categories = arr.reduce((acc, cur) => {
acc[cur.category] = (acc[cur.category] || 0) + 1
return acc;
}, {})
console.log(categories)
edit:
Now, after a year a would wrt this like that
const arr = [
{id: 1, name: 'ford', category: 'vehicle'},
{id: 2, name: 'pig', category: 'animal'},
{id: 3, name: 'dog', category: 'animal'},
{id: 4, name: 'chev', category: 'vehicle'},
{id: 5, name: 'cat', category: 'animal'},
{id: 6, name: 'jeep', category: 'vehicle'},
{id: 7, name: 'honda', category: 'vehicle'}
]
const categories = arr.reduce((acc, cur) => Object.assign(acc, {
[cur.category]: (acc[cur.category] || 0) + 1,
}), {})
console.log(categories)
It looks like the category will always exist, so you don't need to check whether it exists, but what it contains; take what it contains and increment that property on the final object:
const arr = [
{id: 1, name: 'ford', category: 'vehicle'},
{id: 2, name: 'pig', category: 'animal'},
{id: 3, name: 'dog', category: 'animal'},
{id: 4, name: 'chev', category: 'vehicle'},
{id: 5, name: 'cat', category: 'animal'},
{id: 6, name: 'jeep', category: 'vehicle'},
{id: 7, name: 'honda', category: 'vehicle'}
]
const final = {};
for (const { category } of arr) {
final[category] = (final[category] || 0) + 1;
};
console.log(final);
You have the right idea regarding looping over the array and checking if the category was already encountered. What you're missing is initializing a counter when you find a new category and incrementing it the next time that category is encountered:
const arr = [
{id: 1, name: 'ford', category: 'vehicle'},
{id: 2, name: 'pig', category: 'animal'},
{id: 3, name: 'dog', category: 'animal'},
{id: 4, name: 'chev', category: 'vehicle'},
{id: 5, name: 'cat', category: 'animal'},
{id: 6, name: 'jeep', category: 'vehicle'},
{id: 7, name: 'honda', category: 'vehicle'}
]
const final = {};
arr.forEach((v) => {
const cat = v.category;
if (cat in final) {
final[cat]++;
} else {
final[cat] = 1;
}
});
console.log(final);
const arr = [
{ id: 1, name: 'ford', category: 'vehicle' },
{ id: 2, name: 'pig', category: 'animal' },
{ id: 3, name: 'dog', category: 'animal' },
{ id: 4, name: 'chev', category: 'vehicle' },
{ id: 5, name: 'cat', category: 'animal' },
{ id: 6, name: 'jeep', category: 'vehicle' },
{ id: 7, name: 'honda', category: 'vehicle' },
]
// this will hold the results
const result = {}
for (const item of arr) {
// we have not encountered such category before
if (result[item.category] === undefined) {
// setting this category to 1
result[item.category] = 1
// we encountered such category before
} else {
// addint +1 to it
result[item.category] += 1
}
}
console.log(result)
Say I have two arrays of objects:
let ar1 = [{
id: 1,
name: 'abc',
job: 'dev'
}, {
id: 2,
name: 'xyz',
job: 'qa'
},{
id: 3,
name: 'pqr',
job: 'dev'
}
];
let arr2 = [{
id: 1,
name: 'abc',
job: 'dev'
},{
id: 2,
name: 'zzz',
job: 'qa'
},{
id: 3,
name: 'pqr',
job: 'dev'
}];
I need to compare them so that I get 'true' and exit the comparison without iterating further as the name is different in the second element between two objects.
I tried with the following code:
private compareObjects(obj1, obj2) {
obj1.forEach((x) => {
obj2.forEach((y) => {
if (x.id === y.id) {
return (!_.isEqual(x, y));
}
});
});
}
I suggest reduce-ing the second array to what's needed for testing the first array: { id : name }. This is a single pass on the second array.
Then use find to test the first array with a single pass that halts on the first mismatch.
let ar1 = [{
id: 1,
name: 'abc',
job: 'dev'
}, {
id: 2,
name: 'xyz',
job: 'qa'
},{
id: 3,
name: 'pqr',
job: 'dev'
}
];
let arr2 = [{
id: 1,
name: 'abc',
job: 'dev'
},{
id: 2,
name: 'zzz',
job: 'qa'
},{
id: 3,
name: 'pqr',
job: 'dev'
}];
let index = arr2.reduce((acc, e) => {
acc[e.id] = e.name
return acc
}, {})
let firstMismatched = ar1.find(e => index[e.id] !== e.name)
console.log(firstMismatched)
How do I get 2 matching id between 2 array object using javascript?
// Array 1
const array1 = [
{id: 1, name: 'milla'},
{id: 2, name: 'alice'}
]
// Array 2
const array2 = [
{id: 3, name: 'bobba', height: '170cm', age: 22},
{id: 2, name: 'alice', height: '169cm', age: 21},
{id: 1, name: 'milla', height: '171cm', age: 24},
{id: 4, name: 'ricky', height: '168cm', age: 32},
]
the expected output is to returned array of object of Array2 that mached with id's on array1
// expected result
[
{id: 2, name: 'alice', height: '169cm', age: 21},
{id: 1, name: 'milla', height: '171cm', age: 24},
]
You could filter and look if the same id exists.
const
array1 = [{ id: 1, name: 'milla' }, { id: 2, name: 'alice' }],
array2 = [{ id: 3, name: 'bobba', height: '170cm', age: 22 }, { id: 2, name: 'alice', height: '169cm', age: 21 }, { id: 1, name: 'milla', height: '171cm', age: 24 }, { id: 4, name: 'ricky', height: '168cm', age: 32 }],
hash = array1.reduce((r, { id }) => (r[id] = true, r), {}),
filtered = array2.filter(({ id }) => hash[id]);
console.log(filtered);
The most efficient way to do this is to generate a map of the IDs in array1 and then filter array2 against those IDs, like so:
let array1 = [{ id: 1, name: 'milla' }, { id: 2, name: 'alice' }];
let array2 = [{ id: 3, name: 'bobba', height: '170cm', age: 22 }, { id: 2, name: 'alice', height: '169cm', age: 21 }, { id: 1, name: 'milla', height: '171cm', age: 24 }, { id: 4, name: 'ricky', height: '168cm', age: 32 }];
let idMap = array1.reduce((res, curr) => (res[curr.id] = true, res), {});
let filtered = array2.filter((item) => idMap[item.id]);
console.log(filtered)
Honestly, this is basic JS, but anyway, here's the solution:
const array1 = [
{id: 1, name: 'milla'},
{id: 2, name: 'alice'}
]
// Array 2
const array2 = [
{id: 3, name: 'bobba', height: '170cm', age: 22},
{id: 2, name: 'alice', height: '169cm', age: 21},
{id: 1, name: 'milla', height: '171cm', age: 24},
{id: 4, name: 'ricky', height: '168cm', age: 32},
]
const map = array1.reduce((a, c) => ({ ...a, [c.id]: true }), {});
const array3 = array2.filter(item => map[item.id]);
console.log(array3);
I'm having an array of this:
var arr = [
{
name: 'John',
age: {
id: 1,
value: 'less than 19'
}
},
{
name: 'Doe',
age: {
id: 2,
value: 'more than 19'
}
}
]
How can I use underscore to flatten the age object in the array. The expected result is:
arr == [
{
name: 'John',
age: 'less than 19'
},
{
name: 'Doe',
age: 'more than 19'
}
];
Thanks,
You can try this:
var result = arr.map(function(item) {
return {
name: item.name,
age: item.age.value
};
});
Demo:
var arr = [{
name: 'John',
age: {
id: 1,
value: 'less than 19'
}
}, {
name: 'Doe',
age: {
id: 2,
value: 'more than 19'
}
}];
var result = arr.map(function(item) {
return {
name: item.name,
age: item.age.value
};
});
console.log(result);
I hope this will help you.
using old style :D
var arr = [
{
name: 'John',
age: {
id: 1,
value: 'less than 19'
}
},
{
name: 'Doe',
age: {
id: 2,
value: 'more than 19'
}
}
];
var newArr = [];
arr.forEach(function(item, idx) {
newArr.push({
name: item.name,
age: item.age.value
});
});
console.log(newArr);