I am trying to handle JSON arrays to extract key value pair from the keys available from user selection.
This is not real time json example...It is just a sample
Example of JSON
var personnel = [
{
id: 5,
name: "Luke Skywalker",
pilotingScore: 98,
shootingScore: 56,
isForceUser: true,
},
{
id: 82,
name: "Sabine Wren",
pilotingScore: 73,
shootingScore: 99,
isForceUser: false,
skills:{
'skill1':'vision',
'skill2':'strength'
}
},
{
id: 22,
name: "Zeb Orellios",
pilotingScore: 20,
shootingScore: 59,
isForceUser: false,
},
{
id: 15,
name: "Ezra Bridger",
pilotingScore: 43,
shootingScore: 67,
isForceUser: true,
skills:{
'skill1':'vision',
'skill2':'strength'
}
},
{
id: 11,
name: "Caleb Dume",
pilotingScore: 71,
shootingScore: 85,
isForceUser: true,
},
];
sample_arr = [id,name,skills.skill1];
let op = personnel.map(md => {
return { id: md.id,name:md.name,skills{skill1:md.skills.skill1}};
});
console.log(JSON.stringify(op,null,2))
I wanted to get key value pair like below.
[
{
"id": 5,
"name": "Luke Skywalker"
},
{
"id": 82,
"name": "Sabine Wren",
"skills":{
"skill1": 'vision'
}
},
{
"id": 22,
"name": "Zeb Orellios"
},
{
"id": 15,
"name": "Ezra Bridger"
},
{
"id": 11,
"name": "Caleb Dume"
}
]
I now updated the my problem statement.
Requirement:
Extract all JSON values selected by the user to a new array. This will save more time as the json is 700MB all the way and it is time consuming to handle on every request
You have the user selections stored in the array? If so, you could do something like:
let sample_arr = ['id', 'name']
let op = personnel.map(md => {
let user = {}
sample_arr.forEach(val => {
if (md[val]) {
user[val] = md[val]
}
})
return user
})
Here's a simple function to do this:
const project = (keys) => (xs) =>
xs .map (x => keys .reduce ( (a, k) => ({...a, [k]: x[k]}), {} ))
var personnel = [{id:5,name:"Luke Skywalker",pilotingScore:98,shootingScore:56,isForceUser:true},{id:82,name:"Sabine Wren",pilotingScore:73,shootingScore:99,isForceUser:false,skills:{skill1:"vision",skill2:"strength"}},{id:22,name:"Zeb Orellios",pilotingScore:20,shootingScore:59,isForceUser:false},{id:15,name:"Ezra Bridger",pilotingScore:43,shootingScore:67,isForceUser:true,skills:{skill1:"vision",skill2:"strength"}},{id:11,name:"Caleb Dume",pilotingScore:71,shootingScore:85,isForceUser:true}];
console .log (
project (['id', 'name']) (personnel)
)
The name project is from Codd's early papers on relational databases; it's similar in feel to SQL's select statement.
Update
The answer from KellyKapoor has one feature the above lacks: it only includes the property name if the data has it (so no skills: undefined.)
It's not clear which behavior the OP is looking for, but this minor modification offers that feature
const project2 = (keys) => (xs) =>
xs .map (x => keys .reduce ((a, k) => ({...a, ...(k in x ? {[k]: x[k]} : {}) }), {} ))
var personnel = [{id:5,name:"Luke Skywalker",pilotingScore:98,shootingScore:56,isForceUser:true},{id:82,name:"Sabine Wren",pilotingScore:73,shootingScore:99,isForceUser:false,skills:{skill1:"vision",skill2:"strength"}},{id:22,name:"Zeb Orellios",pilotingScore:20,shootingScore:59,isForceUser:false},{id:15,name:"Ezra Bridger",pilotingScore:43,shootingScore:67,isForceUser:true,skills:{skill1:"vision",skill2:"strength"}},{id:11,name:"Caleb Dume",pilotingScore:71,shootingScore:85,isForceUser:true}];
console .log (
project2 (['id', 'name', 'skills']) (personnel)
)
Whats the problem with this?
let op = personnel.map(md => {
return { id: md.id,name:md.name};
});
You can create a function which extracts the props from an object based on a passed array of keys:
var data = [ { id: 5, name: "Luke Skywalker", pilotingScore: 98, shootingScore: 56, isForceUser: true, }, { id: 82, name: "Sabine Wren", pilotingScore: 73, shootingScore: 99, isForceUser: false, skills:{ 'skill1':'vision', 'skill2':'strength' } }, { id: 22, name: "Zeb Orellios", pilotingScore: 20, shootingScore: 59, isForceUser: false, }, { id: 15, name: "Ezra Bridger", pilotingScore: 43, shootingScore: 67, isForceUser: true, skills:{ 'skill1':'vision', 'skill2':'strength' } }, { id: 11, name: "Caleb Dume", pilotingScore: 71, shootingScore: 85, isForceUser: true, }, ];
let pick = (obj, fields) => Object.keys(obj)
.reduce((r,c) => (fields.includes(c) ? r[c] = obj[c] : null, r), {})
let result = data.map(x => pick(x, ['id', 'name', 'skills']))
console.log(result)
Then all you need is to loop though via Array.map to pick from all objects.
Related
I'm trying to filter the array by the numbers. Basically, car with id 48 should be deleted because it does not exist on numbers
What am I missing here??
const numbers = [49, 482, 49, 49, 49, 1135, 49, 1709, 1044, 1016, 30];
const array = [{
cars: [{
id: 48
}, {
id: 49
}]
}];
array.forEach(elem => elem.cars.filter(car => !numbers.includes(car.id)));
console.log(array);
I want to keep the same structure, I just want tot delete the car with id 48
You can use a nested forEach
const numbers = [49, 482, 49, 49, 49, 1135, 49, 1709, 1044, 1016, 30];
const array = [{
cars: [{
id: 48
}, {
id: 49
}]
}];
array.forEach(elm => {
const cars = [];
elm.cars.forEach(car => {
if(numbers.includes(car.id)) {
cars.push({id: car.id});
}
});
elm.cars = cars;
});
console.log(array);
Or a reduce within forEach
const numbers = [49, 482, 49, 49, 49, 1135, 49, 1709, 1044, 1016, 30];
const array = [{
cars: [{
id: 48
}, {
id: 49
}]
}];
array.forEach(elm => {
elm.cars = elm.cars.reduce((acc, curr) => {
if (numbers.includes(curr.id)) {
acc.push({
id: curr.id
});
}
return acc;
}, []);
});
console.log(array);
You could use Array.reduce() to acheive the expected result.
The idea is to change the filter condition which allows to keep the car objects id found in the numbers array and eliminate rest.
In your approach Array.forEach is just iteration without returning anything and Array.filter does not mutate the actual array.
const numbers = [49, 482, 49, 49, 49, 1135, 49, 1709, 1044, 1016, 30];
const array = [
{
cars: [
{
id: 48,
},
{
id: 49,
},
],
},
];
const res = array.reduce((prev, curr) => {
prev.push({ cars: curr.cars.filter((car) => numbers.includes(car.id)) });
return prev;
}, []);
console.info("result::", res);
const numbers = [49, 482, 49, 49, 49, 1135, 49, 1709, 1044, 1016, 30];
const array = [
{
cars: [{id: 48,},{id: 49,}],
},
];
array.forEach((elem) => {
const elemCopy = elem;
elemCopy.cars = elem.cars.filter((car) => numbers.includes(car.id))
});
console.log(array);
Please refer the code, while iterating over array we can mutate the cars array.
I've got some headers and peopleData:
const headers = ["name", "age", "nationality"]
const peopleData = [
["John", 31, "Spanish"],
["Jane", 41, "Italian"],
["Johnson", 11, "Thai"],
["Rob", 13, "Japanese"],
]
I want to combine both and return an array of objects looking like:
[{
name: "John",
age: 31,
nationality: "Spanish"
}, {
name: "Jane",
age: 41,
nationality: "Italian"
}, {
name: "Johnson",
age: 11,
nationalityL: "Thai"
}, {
name: "Rob",
age: 13,
nationality: "Japanese"
}]
So far I came up to this:
const people = peopleData.map((person, i) => {
return headers.map((header, index) => {
return {
[header]: person[index]
}
})
})
This solution does not work since it creates nested objects:
[[{
name: "John"
}, {
age: 31
}, {
nationality: "Spanish"
}], [{
name: "Jane"
}, {
age: 41
}, {
nationality: "Italian"
}], [{
name: "Johnson"
}, {
age: 11
}, {
nationality: "Thai"
}], [{
name: "Rob"
}, {
age: 13
}, {
nationality: "Japanese"
}]]
Example below:
Credit to Andreas comment, better performant below
const headers = ["name", "age", "nationality"];
const peopleData = [
["John", 31, "Spanish"],
["Jane", 41, "Italian"],
["Johnson", 11, "Thai"],
["Rob", 13, "Japanese"],
];
const o = peopleData.map(a =>
a.reduce((acc, b, i) => {
acc[headers[i]] = b;
return acc;
}, {})
);
console.log(o);
In one line-er, but less performent
const headers = ["name", "age", "nationality"];
const peopleData = [
["John", 31, "Spanish"],
["Jane", 41, "Italian"],
["Johnson", 11, "Thai"],
["Rob", 13, "Japanese"],
];
const o = peopleData.map(a =>
a.reduce((acc, b, i) => ({ ...acc, [headers[i]]: b }), {})
);
console.log(o);
You can wrap your inner .map() in a call to Object.fromEntries() which will build an object for you - it takes an array of [[key, value],...] pairs, and so you can change your inner map to return a [key, value] pair array instead of objects like so:
const headers = ["name", "age", "nationality"];
const peopleData = [ ["John", 31, "Spanish"], ["Jane", 41, "Italian"], ["Johnson", 11, "Thai"], ["Rob", 13, "Japanese"], ];
const res = peopleData.map(person => Object.fromEntries(person.map(
(val, i) => [headers[i], val]
)));
console.log(res);
Or, you can stick with your approach of returning an array of objects, but then merge the objects within the array together using Object.assign() and the spread syntax ...:
const headers = ["name", "age", "nationality"];
const peopleData = [ ["John", 31, "Spanish"], ["Jane", 41, "Italian"], ["Johnson", 11, "Thai"], ["Rob", 13, "Japanese"], ];
const res = peopleData.map(person => Object.assign(...person.map(
(val, i) => ({[headers[i]]: val})
)));
console.log(res);
A simply solution easy to understand! Iterate all peopleData and put them in a new object using the array headers:
const headers = ["name", "age", "nationality"];
const peopleData = [["John", 31, "Spanish"],["Jane", 41, "Italian"],["Johnson", 11, "Thai"],["Rob", 13, "Japanese"]];
let result = [];
peopleData.forEach((e, i) => { //iterate data
result[i] = {};
result[i][headers[0]] = e[0];
result[i][headers[1]] = e[1];
result[i][headers[2]] = e[2];
});
console.log(result);
Please guide me with the right way to get this:
Supose i have this data:
var personnel = [
{
id: 5,
name: "Luke Skywalker",
pilotingScore: 98,
shootingScore: 56,
isForceUser: true,
},
{
id: 82,
name: "Sabine Wren",
pilotingScore: 73,
shootingScore: 99,
isForceUser: false,
},
{
id: 22,
name: "Zeb Orellios",
pilotingScore: 20,
shootingScore: 59,
isForceUser: false,
}
];
and i need the result as this:
{ 5: "Luke Skywalker", 82:"Sabine Wren", 22: "Zeb Orellios"}
i have tried with map i also tried foreach, i can not get some approach.
thankyou
I'd use reduce
personnel.reduce((acc, i) => Object.assign(acc, {[i.id]: i.name}), {})
Try this:
var res = {};
for (p of personnel) {
res[p.id] = p.name;
}
Use Array.map() to create an array of [id, name] pairs, and convert to an object using Object.fromEntries():
const personnel = [{"id":5,"name":"Luke Skywalker","pilotingScore":98,"shootingScore":56,"isForceUser":true},{"id":82,"name":"Sabine Wren","pilotingScore":73,"shootingScore":99,"isForceUser":false},{"id":22,"name":"Zeb Orellios","pilotingScore":20,"shootingScore":59,"isForceUser":false}];
const result = Object.fromEntries(personnel.map(o => [o.id, o.name]));
console.log(result);
I have the following JavaScript object. I need to generate a new array of objects from the given object. What is the approach I should take in JavaScript?
const ObjOfObj = {
'virus': [
{
'2016': 67,
'2017': 59,
'2018': 18,
'2019': 1
}
],
'cure': [
{
'2016': 51,
'2017': 50,
'2018': 16,
'2019': 1
}
]
};
How can I transform or pivot to generate the following array of objects?
const ArrOfObj = [
{'year': '2016', 'virus': 67, 'cure' : 51},
{'year': '2017', 'virus': 59, 'cure' : 50},
{'year': '2018', 'virus': 18, 'cure' : 16},
{'year': '2019', 'virus': 1, 'cure' : 1},
]
you can use a reduce function like this.
const ObjOfObj = {
'virus': [
{
'2016': 67,
'2017': 59,
'2018': 18,
'2019': 1
}
],
'cure': [
{
'2016': 51,
'2017': 50,
'2018': 16,
'2019': 1
}
]
};
const groupBy = (obj) => {
const keys = Object.keys(obj);
const mapping = keys.reduce((acc, k) => {
obj[k].forEach(item => {
Object.keys(item).forEach(yearKey => {
tracked = acc[yearKey];
if (!tracked) {
acc[yearKey] = {
year: yearKey
};
}
acc[yearKey][k] = (acc[yearKey][k] | 0) + item[yearKey];
});
});
return acc;
}, {});
return Object.entries(mapping);
};
console.log(groupBy(ObjOfObj));
var json =
[
{
id: 11,
name:"app1",
family:"apps",
caseID: 123,
order:1
},
{
id: 12,
name:"app1",
family:"apps",
caseID: 123,
order:2
},
{
id: 13,
name:"app1",
family:"apps",
caseID: 123,
order:3
},
{
id: 14,
name:"app2",
family:"tools",
caseID: 129,
order:1
},
{
id: 15,
name:"app2",
family:"tools",
caseID: 129,
order:2
},
{
id: 16,
name:"app3",
family:"utils",
caseID: 120,
order:1
},
{
id: 17,
name:"app3",
family:"utils",
caseID: 120,
order:2
},
id: 18,
name:"app3",
family:"utils",
caseID: 150,
order:null
}
]
Hello, I would like to sort the array above by the highest "order" key and return the filtered array below. The common key is the caseID. Also, If the order key is null return it.
I've searched and tested some functions and loops but cannot seem to get it rite. Any help will be much appreciated. I'd prefer es2015 if possible.
Thank you!
filtered =
[
{
id: 13,
name:"app1",
family:"apps",
caseID: 123,
order:3
},
{
id: 15,
name:"app2",
family:"tools",
caseID: 129,
order:2
},
{
id: 17,
name:"app3",
family:"utils",
caseID: 120,
order:2
},
{
id: 18,
name:"app3",
family:"utils",
caseID: 150,
order:null
}
]
I would start by getting rid of dupes. You can do this with reduce() and assigning to an object keyed to caseID. You can simultaneously avoid any object with a smaller order than one you've already seen. Then you can take the values of that hash which will be the unique objects base on caseID and sort them like you normally would. For example:
var json = [{ "id": 11, "name":"app1", "family":"apps", "caseID": 123, "order":1},{ "id": 12, "name":"app1", "family":"apps", "caseID": 123, "order":2},{ "id": 13, "name":"app1", "family":"apps", "caseID": 123, "order":3},{ "id": 14, "name":"app2", "family":"tools", "caseID": 129, "order":1},{ "id": 15, "name":"app2", "family":"tools", "caseID": 129, "order":2},{ "id": 16, "name":"app3", "family":"utils", "caseID": 120, "order":1},{ "id": 17, "name":"app3", "family":"utils", "caseID": 120, "order":2},{ "id": 18, "name":"app3", "family":"utils", "caseID": 150, "order":null},]
// get just the filtered items based on caseID
// picking out only the largest
let filtered = json.reduce((a,c) => {
if (!a[c.caseID] || a[c.caseID]['order'] < c.order) a[c.caseID] = c
return a
}, {})
// basic sort
let result = Object.values(filtered).sort((a,b) => b.order - a.order)
console.log(result)
You could use a caseID hashtable and override results you find later if order is higher:
const result = [], hash = {};
for(const el in json) {
const exists = hash[el.caseId];
if(exists) {
if(el.order > exists.order)
Object.assign(exists, el);
} else {
result.push(hash[el.caseId] = {...el});
}
}
You can try following
Method
Create an object with unique case ID as key and value being the item with highest order
Sort based on order
// Code goes here
var json = [{"id":11,"name":"app1","family":"apps","caseID":123,"order":1},{"id":12,"name":"app1","family":"apps","caseID":123,"order":2},{"id":13,"name":"app1","family":"apps","caseID":123,"order":3},{"id":14,"name":"app2","family":"tools","caseID":129,"order":1},{"id":15,"name":"app2","family":"tools","caseID":129,"order":2},{"id":16,"name":"app3","family":"utils","caseID":120,"order":1},{"id":17,"name":"app3","family":"utils","caseID":120,"order":2},{"id":18,"name":"app3","family":"utils","caseID":150,"order":null}];
var map = {};
// Create a map of unique case ID's with highest order
json.forEach((item) => {
if(map[item.caseID]) {
if(map[item.caseID].order < item.order) {
map[item.caseID] = item;
}
} else {
map[item.caseID] = item;
}
});
// Sorting the array based on order
var result = Object.values(map).sort((a,b) => b.order-a.order);
console.log(result);
In ES6:
json.sort((a, b) => a.caseID > b.caseID);
let bad_order = json.filter(v => v.order === null);
let good_order = json.filter(v => v.order !== null);
Example
In ES5:
json.sort(function(a, b) { return a.caseID > b.caseID; });
var bad_order = [];
var good_order = [];
for(var i = 0; i < json.length; i++){
if(json[i].order === null)
bad_order.push(json[i]);
else
good_order.push(json[i]);
}
Example
Use reduce method to create an object where the keys will be the caseID.While creating the object check if the value of the order is more or less that the current order value.If the current value is less the than the new value, replace it with new value.
Then use Object.values(object) to create an array of values from the object
var json = [{
"id": 11,
"name": "app1",
"family": "apps",
"caseID": 123,
"order": 1
},
{
"id": 12,
"name": "app1",
"family": "apps",
"caseID": 123,
"order": 2
},
{
"id": 13,
"name": "app1",
"family": "apps",
"caseID": 123,
"order": 3
},
{
"id": 14,
"name": "app2",
"family": "tools",
"caseID": 129,
"order": 1
},
{
"id": 15,
"name": "app2",
"family": "tools",
"caseID": 129,
"order": 2
},
{
"id": 16,
"name": "app3",
"family": "utils",
"caseID": 120,
"order": 1
},
{
"id": 17,
"name": "app3",
"family": "utils",
"caseID": 120,
"order": 2
}, {
"id": 18,
"name": "app3",
"family": "utils",
"caseID": 150,
"order": null
}
]
var m = json.reduce(function(acc, curr, index) {
if (acc[curr['caseID']] === undefined) {
acc[curr['caseID']] = curr;
} else {
if (acc[curr['caseID']].order < curr.order) {
acc[curr['caseID']] = curr;
}
}
return acc;
}, {})
console.log(Object.values(m))
This should help you filter array of objects.
var filteredMap = {};
json.forEach(function (item) {
filteredMap[item.caseID] = item;
});
var filteredArray = [];
for (var key in filteredMap) {
filteredArray.push(filteredMap[key]);
}
console.log(JSON.stringify(filteredArray));
Sort by order and caseID and then filter by caseID,Here is the code:
var json =
[
{
id: 11,
name:"app1",
family:"apps",
caseID: 123,
order:1
},
{
id: 12,
name:"app1",
family:"apps",
caseID: 123,
order:2
},
{
id: 13,
name:"app1",
family:"apps",
caseID: 123,
order:3
},
{
id: 14,
name:"app2",
family:"tools",
caseID: 129,
order:1
},
{
id: 15,
name:"app2",
family:"tools",
caseID: 129,
order:2
},
{
id: 16,
name:"app3",
family:"utils",
caseID: 120,
order:1
},
{
id: 17,
name:"app3",
family:"utils",
caseID: 120,
order:2
}, {
id: 18,
name:"app3",
family:"utils",
caseID: 150,
order:null
}
]
var obj = {}
var arr = json.sort(function(a, b) {
return b.order - a.order
}).sort(function(a, b) {
return a.caseId - b.caseId
}).filter(function(item, index, array){
return obj.hasOwnProperty(item.caseID) ? false : (obj[item.caseID] = true)
})
console.log(arr)
demo: http://jsbin.com/qabehorike/edit?js,console,output