I want to create a datasource dynamically for my table from a array of objects.
Required datasource value:
values = [
{
name: "Super Admin"
cv: 1
assessment1_title: score/status
assessment2_title: score/status
interview1_title: score/status
interview2_title: score/status
}
]
I have the following array of object:
data = {
"assessments": [
{
"id": 6,
"title": "PHP Laravel Developer",
"type": "Objective"
},
{
"id": 7,
"title": "Laravel Developer",
"type": "Objective"
}
],
"candidates": [
{
"id": 11,
"user_id": 1,
"user_name": "Super Admin",
"assessments": [
{
"id": 1,
"score": 5,
"duration": 1170,
"status": {
"id": 22,
"name": "completed"
}
},
{
"id": 2,
"score": 0,
"duration": 0,
"status": {
"id": 22,
"name": "Pending"
}
}
]
}
]
}
where the value of assessment_title will be dynamically generated from data.assessments.map(({title}) => title) and the value will be one of score and status
data.canditates.map(res => res.assessments.map(res2=> {
if res2.status.id ==22 {
value = res2.score
} else {
value = res2.status.name
}
})
);
I want to make the required datasource value. Thanks in advance
You can get the desired result by using reduce on candidates and then forEach assessments element add title and score/status.
const data = {"assessments":[{"id":6,"title":"PHP Laravel Developer","type":"Objective"},{"id":7,"title":"Laravel Developer","type":"Objective"}],"candidates":[{"id":11,"user_id":1,"user_name":"Super Admin","assessments":[{"id":1,"score":5,"duration":1170,"status":{"id":22,"name":"completed"}},{"id":2,"score":0,"duration":0,"status":{"id":22,"name":"Pending"}}]}]}
const result = data.candidates.reduce((r, c) => {
const obj = {}
obj.cv = c.user_id;
obj.name = c.user_name;
c.assessments.forEach((e, i) => {
const {score, status: {name}} = e;
const {title} = data.assessments[i];
obj[title] = e.status.id === 22 ? name : score;
})
r.push(obj)
return r;
}, [])
console.log(result)
You could also create a bit more flexible solution that will work in case you have more then two keys in original object.
const data = {"assessments":[{"id":6,"title":"PHP Laravel Developer","type":"Objective"},{"id":7,"title":"Laravel Developer","type":"Objective"}],"interviews":[{"id":1,"title":"Interview 1"},{"id":2,"title":"Interview 2"}],"candidates":[{"id":11,"user_id":1,"user_name":"Super Admin","interviews":[{"id":1,"score":3,"status":{"name":"completed"}},{"id":2,"score":0,"status":{"name":"pending"}}],"assessments":[{"id":1,"score":5,"duration":1170,"status":{"id":22,"name":"completed"}},{"id":2,"score":0,"duration":0,"status":{"id":22,"name":"Pending"}}]}]}
const result = data.candidates.reduce((r, c) => {
const obj = {}
obj.cv = c.user_id;
obj.name = c.user_name;
Object.keys(data).forEach(k => {
if(k !== 'candidates') {
data[k].forEach((e, i) => {
const {title} = e;
const {score, status: {name}} = c[k][i];
obj[title] = `${score}/${name}`
})
}
})
r.push(obj)
return r;
}, [])
console.log(result)
My solution would be something like below.
data = {
assessments: [
{
id: 6,
title: "PHP Laravel Developer",
type: "Objective"
},
{
id: 7,
title: "Laravel Developer",
type: "Objective"
}
],
candidates: [
{
id: 11,
user_id: 1,
user_name: "Super Admin",
assessments: [
{
id: 6,
score: 5,
duration: 1170,
status: {
id: 22,
name: "completed"
}
},
{
id: 7,
score: 0,
duration: 0,
status: {
id: 21,
name: "Pending"
}
}
]
}
]
};
assessments_map = data.assessments.reduce((acc, val) => {
const {id,...rest} = val;
acc[id] = rest;
return acc
}, {});
assessments_map;
a = data.candidates.map((candidate) => {
return {name: candidate.user_name,
...candidate.assessments.reduce((acc, assessment) => {
acc[assessments_map[assessment.id].title] =
assessment.status.id == 22
? assessment.score
: assessment.status.name;
return acc;
}, {})
}
});
console.log(a);
Related
I have an array as follows:
[
{
"id":1,
"active":1,
"name":"paris"
},
{
"id":2,
"active":0,
"name":"london"
},
{
"id":3,
"active":1,
"name":"Australia"
},
{
"id":4,
"active":0,
"name":"india"
}
]
I have a method which recieved a object as argument. object looks something like this:
{
"id":4,
"active":0,
"name":"india"
}
In that method I want to check if element with particular id is present or not. If present I want to replace element in array with the element received in arguments. If element with that id is not found that add that element to the array. How can I do that?
you can do like this
let testArr = [
{
id: 1,
active: 1,
name: "paris",
},
{
id: 2,
active: 0,
name: "london",
},
{
id: 3,
active: 1,
name: "Australia",
},
{
id: 4,
active: 0,
name: "india",
},
];
let testObj = {
id: 4,
active: 0,
name: "india1",
};
let findIndex = testArr.findIndex((data) => data.id === testObj.id);
if (findIndex != -1) {
testArr[findIndex].active = testObj.active;
testArr[findIndex].name = testObj.name;
} else {
testArr = [...testArr, testObj];
}
console.log("testArr=>", testArr);
I'd propose the following: in any case you want to have the new object included in the given array:
Remove Object with id from array
Add new Object
Could work as following:
let testArr = [ ... ]
let testObj = { ... }
testArr = testArr.filter(element => element.id !== testObj.id)
testArr.push(testObj)
If it's necessary to keep the object in the array:
let testArr = [ ... ]
let testObj = { ... }
const foundElement = testArr.find(element => element.id === testObj.id)
if (foundElement) {
foundElement.active = testObj.active
foundElement.name = testObj.name
} else {
testArr.push(testObj)
}
you can do something like this
const update = (data, item) => {
const withId = data.reduce((res, curr) => ({
...res,
[curr.id]: curr
}), {})
withId[item.id] = item
return Object.values(withId)
}
let testArr = [
{
id: 1,
active: 1,
name: "paris",
},
{
id: 2,
active: 0,
name: "london",
},
{
id: 3,
active: 1,
name: "Australia",
},
{
id: 4,
active: 0,
name: "india",
},
];
let testObj = {
id: 4,
active: 0,
name: "india1",
};
const updated = update(testArr, testObj)
console.log(updated)
unable to change the items based on id and expected result should be in output format
const items = [
{ id: 1, value: "first" },
{ id: 2, value: "second" },
{ id: 3, value: "third" }
];
const expectedOutput = [
{ id: 1, value: "first" },
{ id: 2, value: "newvalue" },
{ id: 3, value: "third" }
]
function getData(value, id) {
return items.map((_each)=> {
if(_each.id === id) {
//need to update items with id=2
}
})
}
console.log(getData("newvalue", 2))
let inputArr = {
"data": [{
"id": 1,
"value": "first",
"row": "A"
},
{
"id": 2,
"value": "second",
"row": "A"
},
{
"id": 3,
"value": "Third",
"row": "B"
},
{
"id": 4,
"value": "Fourth",
"row": "B"
}
]
}
function format(inputArr) {
let arr = []
let obj = {};
inputArr.data.forEach(el => {
obj = {
...obj,
[el.row]: [...(obj[el.row] || []) , el.value],
}
});
arr.push(obj);
return arr;
}
let outputArr = format(inputArr)
console.log(outputArr)
let expectedOutput = [{
"A": ["first", "second"]
}, {
"B": ["Third", "Fourth"]
}]
#chidananda,
Map callback should return updated item. Minor modification to your code would work!
const items = [
{ id: 1, value: "first" },
{ id: 2, value: "second" },
{ id: 3, value: "third" }
];
const expectedOutput = [
{ id: 1, value: "first" },
{ id: 2, value: "newvalue" },
{ id: 3, value: "third" }
]
function getData(value, id) {
return items.map((_each)=> {
if(_each.id === id) {
_each.value = value;
}
return _each; // Return the modified item
})
}
console.log(getData("newvalue", 2))
What I would like to achieve is that I want to display fromUsers one by one, but no duplicates. So if I have 2 messages from the same John (same fromUserId), then I want this John's name to appear only once, because it's the same John with the same fromUserId. Then once I click on John's name, then I would see 2 messages (hi + hey). We cannot get rid of any objects because the message are different and I still need to display these messages. Is it possible to implement this? I am using Node.js, Mongodb, Mongoose, and React.
[
{
"message": "hi",
"fromUser": "John",
"fromUserId": "5edb1f10b82175355479f05a",
},
{
"message": "hey",
"fromUser": "John",
"fromUserId": "5edb1f10b82175355479f05a",
},
{
"message": "ola",
"fromUser": "Jane",
"fromUserId": "5ed9d49c7e516616600eb693",
}
]
Render:
<div>
{this.state.from.map((from) => {
return <div key={from._id}>{from.fromUser}</div>;
})}
</div>
Axios get request:
axios.get('/api/getMessage', { headers: { 'X-Auth-Token': token } }).then((res) => {
this.setState({ from: res.data });
});
State in class component:
this.state = {
message: '',
from: [],
};
Uses an object map to collect messages into arrays. Resultant data in the form of:
[ { _id, fromUser, messages} ... ]
const fromCollectMessages = from =>
Object.values(from.reduce((chats,{message:m, fromUserId: _id, fromUser})=>{
chats[_id] = chats[_id] || { _id, fromUser }
chats[_id].messages = chats[_id].messages || []
chats[_id].messages.push(m)
return chats
},{}))
const data=[
{
"message": "hi",
"fromUser": "John",
"fromUserId": "5edb1f10b82175355479f05a",
},
{
"message": "hey",
"fromUser": "John",
"fromUserId": "5edb1f10b82175355479f05a",
},
{
"message": "ola2",
"fromUser": "Jane",
"fromUserId": "5ed9d49c7e516616600eb693",
},
{
"message": "hi2",
"fromUser": "John",
"fromUserId": "5edb1f10b82175355479f05a",
},
{
"message": "ola",
"fromUser": "Jane",
"fromUserId": "5ed9d49c7e516616600eb693",
}
]
console.log(fromCollectMessages(data))
const { Component } = React,
{ render } = ReactDOM,
el = document.getElementById('app')
class Name extends Component {
constructor(props) {
super(props)
this.state = {from: fromCollectMessages(props.from)}
}
render() {
return (
<div>
{this.state.from.map((from) => {
return <div key={from._id} style={{cursor:'pointer'}}
onClick={()=>alert(from.messages.join('\n'))}>
{from.fromUser}
</div>;
})}
</div>
)
}
}
render(<Name from={data}/>,el)
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="app"></div>
With the given constraints, I'd assume that messages are in order. Also, if they are not then consider adding a timestamp.
Moving forwards, this json can be shown as something like this:
John: hi
John: hey
Jane: ola
But what you're asking for is:
John: hi hey
Jane: ola
Following code will help merge similar users together:
const chats = [
{
"message": "hi",
"fromUser": "John",
"fromUserId": "5edb1f10b82175355479f05a",
},
{
"message": "hey",
"fromUser": "John",
"fromUserId": "5edb1f10b82175355479f05a",
},
{
"message": "ola",
"fromUser": "Jane",
"fromUserId": "5ed9d49c7e516616600eb693",
}
];
userChat = {};
// grouping the chat together
for (const msg of chats) {
let user = msg.fromUserId;
if (userChat[user] === undefined) {
userChat[user] = msg;
} else {
userChat[user].message += " " + msg.message;
}
}
// printing the msg out
for (const user in userChat) {
console.log("User: ", userChat[user].fromUser);
console.log("Message: ", userChat[user].message);
}
I've intentionally chosen this way so that it can be extended for multiple uses also. (just in case)
you should use reducer, adapt this code to yours:
const arr = [
{ id: 1, name: "test1", msg: 'hi1' },
{ id: 2, name: "test2", msg: 'hi2' },
{ id: 2, name: "test3", msg: 'hi3' },
{ id: 3, name: "test4", msg: 'hi4' },
{ id: 4, name: "test5", msg: 'hi5' },
{ id: 5, name: "test6", msg: 'hi6' },
{ id: 5, name: "test7", msg: 'hi7' },
{ id: 6, name: "test8", msg: 'hi8' }
];
const filteredArr = arr.reduce((acc, current) => {
const x = acc.find(item => item.id === current.id);
if (!x) {
return [...acc, current];
} else {
return acc.map(x=> x.id === current.id ? ({...x, msg: x.msg + current.msg }) : x)
}
}, []);
console.log(filteredArr)
Result:
[{
id: 1,
msg: "hi1",
name: "test1"
}, {
id: 2,
msg: "hi2hi3",
name: "test2"
}, {
id: 3,
msg: "hi4",
name: "test4"
}, {
id: 4,
msg: "hi5",
name: "test5"
}, {
id: 5,
msg: "hi6hi7",
name: "test6"
}, {
id: 6,
msg: "hi8",
name: "test8"
}]
I have included all messages from an user inside an array messages inside the users object.
let users = [{
"message": "hi",
"fromUser": "John",
"fromUserId": "5edb1f10b82175355479f05a",
},
{
"message": "hey",
"fromUser": "John",
"fromUserId": "5edb1f10b82175355479f05a",
},
{
"message": "ola",
"fromUser": "Jane",
"fromUserId": "5ed9d49c7e516616600eb693",
},
{
"message": "hi",
"fromUser": "John",
"fromUserId": "5edb1f10b82175355479f05a",
},
]
let flags = [],
output = [];
users.forEach(user => {
if (flags[user.fromUserId]) {
output.forEach(item => {
if (item.fromUserId === user.fromUserId) {
item.messages = [...item.messages, user.message]
}
})
} else {
user.messages = [user.message]
flags[user.fromUserId] = true;
output.push(user);
}
})
output will look like this:
output = [{
"message": "hi",
"fromUser": "John",
"fromUserId": "5edb1f10b82175355479f05a",
"messages": ["hi", "hey", "hi"]
},
{
"message": "ola",
"fromUser": "Jane",
"fromUserId": "5ed9d49c7e516616600eb693",
"messages": ["ola"]
}
]
Short answer:
let output = input.reduce( (acc, cur) => {
if(acc.map(item => item.fromUserId).includes(cur.fromUserId)){ //Check if the user is already included in the combined output
let found = acc.find(entry => entry.fromUserId === cur.fromUserId); //If found, combine the messages
found.message.push(cur.message);
return acc;
} else {
cur.message = [cur.message]; //the user is not included in the output yet
acc.push(cur); //so add it to the output
return acc;
}
}, []);
Full answer (Runnable code):
let input = [
{
"message": "hi",
"fromUser": "John",
"fromUserId": "5edb1f10b82175355479f05a",
},
{
"message": "hey",
"fromUser": "John",
"fromUserId": "5edb1f10b82175355479f05a",
},
{
"message": "ola",
"fromUser": "Jane",
"fromUserId": "5ed9d49c7e516616600eb693",
}
];
let output = input.reduce( (acc, cur) => {
if(acc.map(item => item.fromUserId).includes(cur.fromUserId)){
let found = acc.find(entry => entry.fromUserId === cur.fromUserId);
found.message.push(cur.message);
return acc;
} else {
cur.message = [cur.message];
acc.push(cur);
return acc;
}
}, []);
console.log(output);
In my angular 8 application, I have 2 arrays:
array1 = [{
"SubType": "2|3|4|5|6",
},
{
"SubType": "2",
},
{
"SubType": "3|4",
},
{
"SubType": "6",
},
{
"SubType": "3|6",
},
]
&
array2 = [{
"id": 2,
"type": "1",
},
{
"id": 3,
"type": "5",
},
{
"id": 4,
"type": "4",
},
{
"id": 5,
"type": "3",
},
{
"id": 6,
"type": "2",
}
]
I am trying to check each "SubType" in array1 and see if that element(id) is present in array2 and if present assign its "type" to a variable. "SubType" is | separated which I and converting to an array using array1..split('|'). This when assigning to a variable will need to be comma separated. I tried using array filter but I am not able to find a way to loop thorough the second array. Can anyone help?
array1.forEach(reg => {
if (reg.SubType) {
let subTypeTemp = reg.SubType.split('|');
let tempVariable = subTypeTemp.some(ele => {
let stringToassign = '';
for (let i = 0; i < array2.length; i++) {
if (ele == array2[i].id) {
stringToassign += array2[i].type + ",";
}
}
})
}
})
const array1 = [
{
SubType: "2|3|4|5|6"
},
{ SubType: "2" },
{ SubType: "3|4" },
{ SubType: "6" },
{ SubType: "3|6" }
];
const array2 = [
{
id: 2,
type: "1"
},
{ id: 3, type: "5" },
{ id: 4, type: "4" },
{ id: 5, type: "3" },
{ id: 6, type: "2" }
];
const array2Obj = array2.reduce(
(acc, curr) => ({
...acc,
[curr.id]: curr.type
}),
{}
);
const types = [];
array1.forEach(item => {
const sub_types = item.SubType.split("|");
sub_types.forEach(st => {
if (st in array2Obj) {
types.push(array2Obj[st]);
}
});
});
const types_str = [...new Set(types)].join(',');
console.log("types", types_str);
You could take a Map and prevent looping array2 over and over for getting type of a wanted id.
var array1 = [{ SubType: "2|3|4|5|6" }, { SubType: "2" }, { SubType: "3|4" }, { SubType: "6" }, { SubType: "3|6" }],
array2 = [{ id: 2, type: "1" }, { id: 3, type: "5" }, { id: 4, type: "4" }, { id: 5, type: "3" }, { id: 6, type: "2" }],
types = new Map(array2.map(({ id, type }) => [id.toString(), type])),
result = array1.map(({ SubType }) => SubType
.split('|')
.map(Map.prototype.get, types)
.join()
);
console.log(result);
I have two arrays.
STUD = [{"id":1,"name":"Kida"},{"id":2,"name":"Kidb"},{"id":3,"name":"Kidc"},{"id":4,"name":"Kidd"},{"id":5,"name":"Kide"}]
IDCRD = [{"id":3,"status":"Y"},{"id":4,"status":"Y"},{"id":2,"status":"N"},{"id":5,"status":"Y"},{"id":1,"status":"N"}]
Then I have a loop:
for(var i=0;i<STUD.length;i++){
var id = STUD[i][0];
var name = STUD[i][1];
var status = ?
}
I need the status for STUD[i] from IDCRD array having the same ID inside this loop.
Have another loop on IDCRD and match ids of STUD and IDCRD then get the status
STUD = [{
"id": 1,
"name": "Kida"
}, {
"id": 2,
"name": "Kidb"
}, {
"id": 3,
"name": "Kidc"
}, {
"id": 4,
"name": "Kidd"
}, {
"id": 5,
"name": "Kide"
}];
IDCRD = [{
"id": 3,
"status": "Y"
}, {
"id": 4,
"status": "Y"
}, {
"id": 2,
"status": "N"
}, {
"id": 5,
"status": "Y"
}, {
"id": 1,
"status": "N"
}];
for (var i = 0; i < STUD.length; i++) {
var id = STUD[i].id;
var name = STUD[i].name;
for (j = 0; j < IDCRD.length; j++) {
if (STUD[i].id == IDCRD[j].id) {
var status = IDCRD[j].status;
}
}
console.log(id, name, status);
}
The function status should do what you need
var STUD = [{"id":1,"name":"Kida"},{"id":2,"name":"Kidb"},{"id":3,"name":"Kidc"},{"id":4,"name":"Kidd"},{"id":5,"name":"Kide"}];
var IDCRD = [{"id":3,"status":"Y"},{"id":4,"status":"Y"},{"id":2,"status":"N"},{"id":5,"status":"Y"},{"id":1,"status":"N"}];
function status(i){ return IDCRD.filter(w => w.id == STUD[i].id)[0].status }
console.log(status(0));
console.log(status(1));
console.log(status(2));
console.log(status(3));
console.log(status(4));
or if you run with Node you can write
status = i => IDCRD.filter(w => w.id == STUD[i].id)[0].status
You could take a Map and use id as key and take the map for an easy access to the data of IDCRD.
var stud = [{ id: 1, name: "Kida" }, { id: 2, name: "Kidb" }, { id: 3, name: "Kidc" }, { id: 4, name: "Kidd" }, { id: 5, name: "Kide" }],
IDCRD = [{ id: 3, status: "Y" }, { id: 4, status: "Y" }, { id: 2, status: "N" }, { id: 5, status: "Y" }, { id: 1, status: "N" }],
map = IDCRD.reduce((m, o) => m.set(o.id, o), new Map),
result = stud.map(o => Object.assign({}, o, map.get(o.id)));
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Another solution could be using Array#find, but this approach iterates the array for each item to find.
var stud = [{ id: 1, name: "Kida" }, { id: 2, name: "Kidb" }, { id: 3, name: "Kidc" }, { id: 4, name: "Kidd" }, { id: 5, name: "Kide" }],
IDCRD = [{ id: 3, status: "Y" }, { id: 4, status: "Y" }, { id: 2, status: "N" }, { id: 5, status: "Y" }, { id: 1, status: "N" }],
result = stud.map(o => Object.assign({}, o, IDCRD.find(({ id }) => id === o.id)));
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }