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)
Related
I'm trying to find an element on a multidimentionnal array usin JAVASCRIPT function, but I get error
This is my array's data:
export const datas = [
{
id: 1,
firstName: 'John',
tables: [
{ ID: 11, title: 'Lorem' },
{ ID: 12, title: 'Ipsum' },
],
},
{
id: 2,
firstName: 'Doe',
tables: [
{
ID: 22,
title: 'Arke',
nodes: [{ name: 'Name1' }, { name: 'Name2' }, { name: 'Name3' }],
},
{ ID: 23, title: 'Korem' },
],
},
{
id: 3,
firstName: 'Brad',
tables: [
{
ID: 30,
title: 'Mern',
nodes: [{ name: 'Name4' }, { name: 'Name5' }, { name: 'Name6' }],
},
{
ID: 31,
title: 'Full',
nodes: [{ name: 'Name7' }, { name: 'Name8' }, { name: 'Name9' }],
},
],
},
];
I've tried a reccursive function but it's not work, this is my code :
export const findById = (arr, id) => {
for (let o of arr) {
if (o.tables.length > 0) {
let a = findById(o.tables.nodes, 'id');
console.log(a);
}
}
};
I want to print the Object with ID 22, the problem is that I don't have the same structure in each dimension, and it still confuse me..
My Input : 22
My output :
{
ID: 22,
title: 'Arke',
nodes: [{ name: 'Name1' }, { name: 'Name2' }, { name: 'Name3' }],
},
Have you an idea how to edit my function to get my input's response ?
Your recursive function wasn't too far off, you need to check if the item as a tables first before recursively calling it again. And then finally just check the ID in the loop.
eg..
const datas=[{id:1,firstName:"John",tables:[{ID:11,title:"Lorem"},{ID:12,title:"Ipsum"}]},{id:2,firstName:"Doe",tables:[{ID:22,title:"Arke",nodes:[{name:"Name1"},{name:"Name2"},{name:"Name3"}]},{ID:23,title:"Korem"}]},{id:3,firstName:"Brad",tables:[{ID:30,title:"Mern",nodes:[{name:"Name4"},{name:"Name5"},{name:"Name6"}]},{ID:31,title:"Full",nodes:[{name:"Name7"},{name:"Name8"},{name:"Name9"}]}]}];
function findById(arr, ID) {
for (const a of arr) {
if (a.tables) {
const r = findById(a.tables, ID);
if (r) return r;
}
if (a.ID === ID) return a;
}
}
console.log(findById(datas, 22));
if you just need the nested data you can use flatMap and find
const findById = (arr, id) =>
arr
.flatMap(d => d.tables)
.find(t => t.ID === id)
const datas = [{
id: 1,
firstName: 'John',
tables: [{
ID: 11,
title: 'Lorem'
},
{
ID: 12,
title: 'Ipsum'
},
],
},
{
id: 2,
firstName: 'Doe',
tables: [{
ID: 22,
title: 'Arke',
nodes: [{
name: 'Name1'
}, {
name: 'Name2'
}, {
name: 'Name3'
}],
},
{
ID: 23,
title: 'Korem'
},
],
},
{
id: 3,
firstName: 'Brad',
tables: [{
ID: 30,
title: 'Mern',
nodes: [{
name: 'Name4'
}, {
name: 'Name5'
}, {
name: 'Name6'
}],
},
{
ID: 31,
title: 'Full',
nodes: [{
name: 'Name7'
}, {
name: 'Name8'
}, {
name: 'Name9'
}],
},
],
},
];
console.log(findById(datas, 22))
js has amazing array options https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array
the ones which will help you most are probably:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/flatMap
here are some examples
// get the base with id 22
const baseWith22ID = datas.filter(f => f.tables.filter(s => s.id = 22))
// (i guess you want this one) get all elements with id 22
const onlyElementsWith22ID = datas.flatMap(f => f.tables.filter(s => s.id = 22))
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);
I am trying to change the value of single key in an associative array which is inside another assoc array using javascript.
I have an array like this:
let arr = [{
id: 4,
name: 'test',
docs: [{
id: 1,
name: 'abc'
},{
id: 2,
name: 'xyz'
}]
}, {
id: 8,
name: 'test2',
docs: [{
id: 5,
name: 'abc'
},{
id: 7,
name: 'xyz'
}]
}]
I want to change the value of name of xyz to xyz (test), where test is name key of parent object and get final array as Output:
[{
id: 1,
name: 'abc (test)'
},
{
id: 2,
name: 'xyz (test)'
},
{
id: 5,
name: 'abc (test2)'
},
{
id: 7,
name: 'xyz (test2)'
}]
I am using approach.
let docs = new Array();
arr.forEach((item, index) => {
let docx = item.documents.map(item1 => {
item1.name = item1.name + " ("+item.name+")";
});
docs.push(docx);
});
return docs;
this is returning array of undefined array.
Try a flatMap
let arr = [{ id: 4, name: 'test', docs: [{ id: 1, name: 'abc' },{ id: 2, name: 'xyz' }] }, { id: 8, name: 'test2', docs: [{ id: 5, name: 'abc' },{ id: 7, name: 'xyz' }] }]
const output = arr.flatMap(item =>
item.docs.map(({id,name}) => ({ id, name: `${name} (${item.name})` }))
)
console.log(output)
There is an issue in your data, the docs inner array contains an object with duplicate keys:
let arr = [{
id: 4,
name: 'test',
docs: [{
id: 1,
name: 'abc',
id: 2, // <-- duplicate key
name: 'xyz' // <-- duplicate key
}]
},
If I remove the duplication, you can use this code to create a new object with the name value updated to xyz123 if the original value was xyz:
const original = [{
id: 4,
name: 'test',
docs: [{
id: 1,
name: 'abc'
}, {
id: 2,
name: 'xyz'
}]
}, {
id: 8,
name: 'test2',
docs: [{
id: 1,
name: 'abc'
}, {
id: 2,
name: 'xyz'
}]
}];
const updates = original.map(currentObject => {
const newObject = Object.assign(currentObject);
const newDocs = newObject.docs.map(doc => {
const newDoc = Object.assign(doc);
if (newDoc.name === "xyz") {
newDoc.name = "xyz123";
}
return newDoc;
});
newObject.docs = newDocs;
return newObject
});
console.log(updates);
Trying to generate dropdown with deep nested elements.
Incoming data:
111: {id: 111, name: '111' },
222: {id: 222, name: '222' },
333: {id: 333, name: '333', parent: {id: 222} },
444: {id: 444, name: '444', parent: {id: 333} },
555: {id: 555, name: '555' }
I know only parent and I want to generate a tree for React template.
It's going to be like this:
result:
[{
id: 111,
name: '111'
},
{
id: 222,
name: '222',
children: [{
id: 333,
name: '333',
parent: {
id: 222
},
children: [{
id: 444,
name: '444',
parent: {
id: 333
}
}]
}
]
},
{
id: 555,
name: '555'
}
]
You could take temporary object for keeping all references to the same id and build a tree with the parts.
This works for unsorted data as well.
var data = { 111: { id: 111, name: '111' }, 222: { id: 222, name: '222' }, 333: { id: 333, name: '333', parent: { id: 222 } }, 444: { id: 444, name: '444', parent: { id: 333 } }, 555: { id: 555, name: '555' } },
tree = function (object, root) {
var r = [], o = {};
Object.keys(object).forEach(function (k) {
var id = object[k].id;
o[id] = Object.assign(o[id] || {}, object[k]);
if (o[id].parent === root) {
r.push(o[id]);
} else {
o[o[id].parent.id] = o[o[id].parent.id] || {};
o[o[id].parent.id].children = o[o[id].parent.id].children || [];
o[o[id].parent.id].children.push(o[id]);
}
});
return r;
}(data, undefined);
console.log(tree);
.as-console-wrapper { max-height: 100% !important; top: 0; }
I take a time for make a demo, but look at your object is worg no passed any json validator.
var _data = [{
id: '111',
name: '111'
}, {
id: '222',
name: '222',
children: [
{
id: '333',
name: '333',
parent: {
id: '222'
},
children: [
{
id: '444',
name: '444',
parent: {
id: '333'
}
}
]
}]
}
];
console.log(_data);
function make(arr){
var _arr = [];
function _do(arr, _parent){
for(var i=0; i<arr.length;i++){
var _o = {
id: arr[i].id,
name: arr[i].name
};
if(_parent){
_o.parent = _parent;
}
if(arr[i].children){
_do(arr[i].children, arr[i].id);
}
_arr[arr[i].id] = _o;
}
}
_do(arr);
return _arr
};
console.log(make(_data));
You can try following. You can solve n level nesting with it.
var obj = {
111: {id: 111, name: '111' },
222: {id: 222, name: '222' },
333: {id: 333, name: '333', parent: {id: 222} },
444: {id: 444, name: '444', parent: {id: 333} },
555: {id: 555, name: '555' }
};
// Iterate over the object keys and create the tree and only push items which have no parent in response
var response = [];
Object.keys(obj).forEach(function(key) {
var item = obj[key];
if (item.parent) {
obj[item.parent.id].children = obj[item.parent.id].children || [];
obj[item.parent.id].children.push(obj[key]);
} else {
response.push(obj[key]);
}
});
console.log(response);
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);