Related
I am working on Angular 12, in my TS file
I have an array response from a file upload like this-
[
{
"id": "7",
"name": "xyz",
"job": "doctor",
"preference": "1"
},
{
"id": "7",
"name": "xyz",
"job": "nurse",
"preference": "2"
},
{
"id": "7",
"name": "xyz",
"job": "manager",
"preference": "3"
},
{
"id": "7",
"name": "xyz",
"job": "assistant",
"preference": "4"
},
{
"id": "7",
"name": "xyz",
"job": "chairman",
"preference": "5"
},
{
"id": "7",
"name": "xyz",
"job": "designer",
"preference": "6"
}
]
I want to convert this array to an object in JSON like this-
[
{
"id": "7",
"name": "xyz",
"array1": [
{
"date": "today's Date,",
"endDate": "somedate",
"lastUpdatedBy": "someuser",
"array2": [
{
"job": "doctor",
"preference": "1"
},
{
"job": "nurse",
"preference": "2"
},
{
"job": "manager",
"preference": "3"
},
{
"job": "assistant",
"preference": "4"
},
{
"job": "chairman",
"preference": "5"
},
{
"job": "designer",
"preference": "6"
}
]
}
]
}
]
So based on the id and name combination I want to create the object in JSON which will be passed to an API, I've been trying many things by using map or arrays inside array but having a hard time to succeed. Any help would be appreciated.
In map it will not take duplicate keys for same id & name combination. I have tried to create a customized object and loop through it but each time I get a separate result.
After looping through the array I am trying to build an object like this, but it doesn't produce expected result.
my code-
let object = {
id: data[i].id,
name: data[i].name,
array1:[
{
date: dateParam,
endDate: '',
lastUpdatedBy: 'me',
array2: [
{
job: data[i].job,
preference: data[i].preference
}
]
}
]
};
I'd separate this in two steps:
Group the items using id + name as the key
Transform the grouped structure to the desired output
Click here for a working sandbox
Below is the code:
function groupBy<T, TKey>(list: T[], keyGetter: (arg: T) => TKey) {
const map = new Map<TKey, T[]>();
list.forEach((item) => {
const key = keyGetter(item);
const collection = map.get(key);
if (!collection) {
map.set(key, [item]);
} else {
collection.push(item);
}
});
return map;
}
const groupedInput = groupBy(input, (x) => x.id + x.name);
const output = Array.from(groupedInput.entries()).map(([key, value]) => ({
id: value[0].id,
name: value[0].name,
array1: value.map((x) => ({ job: x.job, preference: x.preference }))
}));
console.log(output);
Using input with the data you gave:
const input = [
{
id: "7",
name: "xyz",
job: "doctor",
preference: "1"
},
{
id: "7",
name: "xyz",
job: "nurse",
preference: "2"
},
{
id: "7",
name: "xyz",
job: "manager",
preference: "3"
},
{
id: "7",
name: "xyz",
job: "assistant",
preference: "4"
},
{
id: "7",
name: "xyz",
job: "chairman",
preference: "5"
},
{
id: "7",
name: "xyz",
job: "designer",
preference: "6"
}
];
This will output:
[{
"id": "7",
"name": "xyz",
"array1": [{
"job": "doctor",
"preference": "1"
}, {
"job": "nurse",
"preference": "2"
}, {
"job": "manager",
"preference": "3"
}, {
"job": "assistant",
"preference": "4"
}, {
"job": "chairman",
"preference": "5"
}, {
"job": "designer",
"preference": "6"
}
]
}
]
Lets suppose I have a JSON ListA:
LIST A
[
{
"address": "wellington lane",
"age": "23",
"country": "Australia",
"name": "Mike",
"profession": "Lawyer"
},
{
"address": "Street 25",
"age": "26",
"country": "New Zealand",
"name": "Parks",
"profession": "Engineer"
},
{
"address": "North cross",
"age": "29",
"country": "Korea",
"name": "Wanda",
"profession": "Doctor"
}
]
LIST B
["name","age","address","country","profession"]
The requirement is I need to sort the JSON LIST A according to the array LIST B and the output should look like:
[
{
"name": "Mike",
"age": "23",
"address": "wellington lane",
"country": "Australia",
"profession": "Lawyer"
},
{
"name": "Parks",
"age": "26",
"address": "Street 25",
"country": "New Zealand",
"profession": "Engineer"
},
{
"name": "Wanda",
"age": "29",
"address": "North cross",
"country": "Korea",
"profession": "Doctor"
}
]
How can I sort this out? I have tried this solution, but it seems this is not working.
Ciao, you could try to iterate in both arrays and create an array result with ordered attributes like this:
let input = [
{
"address": "wellington lane",
"age": "23",
"country": "Australia",
"name": "Mike",
"profession": "Lawyer"
},
{
"address": "Street 25",
"age": "26",
"country": "New Zealand",
"name": "Parks",
"profession": "Engineer"
},
{
"address": "North cross",
"age": "29",
"country": "Korea",
"name": "Wanda",
"profession": "Doctor"
}
]
let fields = ["name","age","address","country","profession"]
let result = [];
input.forEach(el => {
let resultobj = {}
fields.forEach(fi => {
resultobj[fi] = el[fi]
})
result.push(resultobj)
})
console.log(result)
Here's a solution using map and reduce:
const arr = [
{
"address": "wellington lane",
"age": "23",
"country": "Australia",
"name": "Mike",
"profession": "Lawyer"
},
{
"address": "Street 25",
"age": "26",
"country": "New Zealand",
"name": "Parks",
"profession": "Engineer"
},
{
"address": "North cross",
"age": "29",
"country": "Korea",
"name": "Wanda",
"profession": "Doctor"
}
];
const order = ["name", "age", "address", "country", "profession"];
const newArr = arr.map(e => order.reduce((obj, key) => ({ ...obj, [key]: e[key] }), {}));
console.log(newArr);
One way to do this without having to rely on an external library:
const arr = [
{
'address': 'wellington lane',
'age': '23',
'country': 'Australia',
'name': 'Mike',
'profession': 'Lawyer',
},
{
'address': 'Street 25',
'age': '26',
'country': 'New Zealand',
'name': 'Parks',
'profession': 'Engineer',
},
{
'address': 'North cross',
'age': '29',
'country': 'Korea',
'name': 'Wanda',
'profession': 'Doctor',
},
];
const keyOrder = ['name', 'age', 'address', 'country', 'profession'];
function applyKeyOrder(obj, keyOrder) {
const res = {};
for (const key of keyOrder) {
res[key] = obj[key];
}
return res;
}
const result = arr.map(element => applyKeyOrder(element, keyOrder));
console.log(result);
Note that this assumes that all keys in the keyOrder-array actually exist in the objects, i.e. fields would get lost if they're not present in the array.
Where "LIST A" is listA and "LIST B" is listB:
const formatList = () => {
return listA.map(item => {
const res = {};
listB.map(label => {
res[label] = item[label];
})
return res;
})
};
console.log(formatList())
I am trying to access key pair values on a array object and setstate but it returns undefined
when i console.log(obj) i see the values but when i try to access them it get undefined
const data =[
[
{
"name": "chris",
"city": "unknown",
"code": "404",
"zip": "345"
},{
"name": "kulo mike",
"city": "america",
"code": "210",
"zip": "43"
}, {
"name": "chris smith",
"city": "unknown",
"code": "918",
"zip": "89"
},
]
]
i tried this
const person = data.filter(
item =>{
item.name == 'chris'
console.log(item.name)
})
and also this
const person = data.filter(
item => item.name === 'kulo mike'
)[0].zip
set state
this.state={
user: person
}
Array inside Array, try to convert your data to :
const data =[
{
"name": "chris",
"city": "unknown",
"code": "404",
"zip": "345"
},{
"name": "kulo mike",
"city": "america",
"code": "210",
"zip": "43"
}, {
"name": "chris smith",
"city": "unknown",
"code": "918",
"zip": "89"
},
]
const user = data.filter(item => item.name === 'kulo mike')[0]
setState({user})
var json = [{
"city": "California",
"name": "Joe",
"age": 17
}, {
"city": "California",
"name": "Bob",
"age": 17
}, {
"city": "California",
"name": "Bob",
"age": 35
}, {
"city": "Texas",
"name": "Bob",
"age": 35
}, {
"city": "Florida",
"name": "Bob",
"age": 35
}
];
I just to no of occurence based on city value i.e output as below.
updatedjson=[{"name":"California","count":3},{"name":"Texas","count":1},{"name":"Florida","count":1}]
using any approah using lodash or javascript
Using Lodash, that would be:
const updatedJson = _(json)
.countBy('city')
.map((count, name) => ({ name, count }))
.value();
const json = [{"city":"California","name":"Joe","age":17},{"city":"California","name":"Bob","age":17},{"city":"California","name":"Bob","age":35},{"city":"Texas","name":"Bob","age":35},{"city":"Florida","name":"Bob","age":35}];
const updatedJson = _(json)
.countBy('city')
.map((count, name) => ({ name, count }))
.value();
console.log(JSON.stringify(updatedJson));
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.5/lodash.min.js"></script>
var json = [{
"city": "California",
"name": "Joe",
"age": 17
}, {
"city": "California",
"name": "Bob",
"age": 17
}, {
"city": "California",
"name": "Bob",
"age": 35
}, {
"city": "Texas",
"name": "Bob",
"age": 35
}, {
"city": "Florida",
"name": "Bob",
"age": 35
}
];
var hash = {}; // will be used for lookup of index of city in updated_json array.
var updated_json = [];
json.forEach(function(item,index){
// if city exists in hash then retrive its position from hash.
if(item.city in hash){
updated_json[hash[item.city]].count++;
}
else{
hash[item.city] = updated_json.length; // store position
updated_json.push({"name":item.city,"count":1});
}
});
console.log(updated_json);
You could collect the count with Map and render the result with the wanted properties.
var data = [{ city: "California", name: "Joe", age: 17 }, { city: "California", name: "Bob", age: 17 }, { city: "California", name: "Bob", age: 35 }, { city: "Texas", name: "Bob", age: 35 }, { city: "Florida", name: "Bob", age: 35 }],
result = Array.from(
data.reduce((m, { city }) => m.set(city, (m.get(city) || 0) + 1), new Map),
([name, count]) => ({ name, count })
);
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Here is how you will get it:
updatedJson = [
{
name: "California",
count: (_.filter(json, item => item.city === "California").length)
}
]
I have an array which is built from the user input. I am trying to loop through a nested key value pair and check whether the values in it matches any value of the given array. The purpose is to make a search facility.
My array :
FilteredSelectedOptions=["20180211","Trax","Vienna","AN01020"]
My key value pair is :
trips = {
"20180201": [{
"journeyId": 1001,
"Number": "001",
"DriverName": "Alex",
"Transporter": {
"id": "T1",
"number": "AN01001",
"Company": "Tranzient"
},
"place": [{
"id": 001,
"value": "Washington DC"
},
{
"id": 002,
"value": "Canberra"
}
],
},
{
"journeyId": 1002,
"Number": "001",
"DriverName": "Tom",
"Transporter": {
"id": "T2",
"number": "AN01002",
"Company": "Trax"
},
"place": [{
"id": 2,
"value": "Canberra"
},
{
"id": 4,
"value": "Vienna"
}
],
},
{
"journeyId": 1003,
"Number": "004",
"DriverName": "Jack",
"Transporter": {
"id": "T3",
"number": "AN01003",
"Company": "Trax"
},
"place": [{
"id": 1,
"value": "Washington DC",
}, {
"id": 4,
"value": "Vienna",
}],
}
],
"20180211": [{
"journeyId": 1004,
"Number": "005",
"DriverName": "Jack",
"Transporter": {
"id": "T3",
"number": "AN01013",
"Company": "Trax"
},
"place": [{
"id": 5,
"value": "Bridgetown"
},
{
"id": 6,
"value": "Ottawa"
},
{
"id": 4,
"value": "Vienna"
}
],
},
{
"journeyId": 1005,
"Number": "005",
"DriverName": "Jerry",
"Transporter": {
"id": "T3",
"number": "AN01020",
"Company": "Trax"
},
"place": [{
"id": 5,
"value": "Bridgetown"
},
{
"id": 6,
"value": "Ottawa"
}
],
}
],
"20180301": [{
"journeyId": 1006,
"Number": "005",
"DriverName": "demy",
"Transporter": {
"id": "T3",
"number": "AN01003",
"Company": "Trax"
},
"place": [{
"id": 5,
"value": "Bridgetown"
},
{
"id": 6,
"value": "Ottawa"
}
],
}],
};
I am expecting output like this :
trips = {
"20180201":
[{
"journeyId": 1002,
"Number": "001",
"DriverName":"Tom",
"Transporter": {
"id": "T2",
"number": "AN01002",
"Company": "Trax"
},
"place": [{"id":002,"value":"Canberra" }]
[{"id":004,"value":"Vienna"}]
},
{
"journeyId": 1003,
"Number": "004",
"DriverName":"Jack",
"Transporter": {
"id": "T3",
"number": "AN01003",
"Company": "Trax"
},
"place": [{"id":001,"value":"Washington DC" }]
[{"id":004,"value":"Vienna"}]
}],
"20180211": [{
"journeyId": 1004,
"Number": "005",
"DriverName":"Jack",
"Transporter": {
"id": "T3",
"number": "AN01013",
"Company": "Trax"
},
"place": [{"id":005,"value":"Bridgetown" }]
[{"id":006,"value":"Ottawa"}]
[{"id":004,"value":"Vienna"}]
},
{
"journeyId": 1005,
"Number": "005",
"DriverName": "Jerry",
"Transporter": {
"id": "T3",
"number": "AN01020",
"Company": "Trax"
},
"place": [{
"id": 5,
"value": "Bridgetown"
},
{
"id": 6,
"value": "Ottawa"
}
]
};
I am trying to use a for loop to check each array elements against the key value pair. What I want to do basically is
for (option in FilteredselectedOptions)
{
//logic
}
I have been able to do it for one particular array value:
const filteredTrips = Object.keys(trips).reduce((tmp, x) => {
const filtered = trips[x].filter(y => y.place && y.place.some(z => z.value === 'Vienna'));
if (filtered.length) {
tmp[x] = filtered;
}
return tmp;
}, {});
But how do I do it for all array elements irrespective of how many elements are inside array. Please help in the loop.
Just an approach by trying to filter with finding a single item in the data.
function filter(object, options) {
const check = v => options.includes(v) || v && typeof v === 'object' && Object.keys(v).some(l => check(v[l]));
var result = {};
Object.keys(object).forEach(function (k) {
var temp = options.includes(k)
? object[k]
: object[k].filter(check);
if (temp.length) {
result[k] = temp;
}
});
return result;
}
var trips = { "20180201": [{ journeyId: 1001, Number: "001", DriverName: "Alex", Transporter: { id: "T1", number: "AN01001", Company: "Tranzient" }, place: [{ id: "001", value: "Washington DC" }, { id: "002", value: "Canberra" }] }, { journeyId: 1002, Number: "001", DriverName: "Tom", Transporter: { id: "T2", number: "AN01002", Company: "Trax" }, place: [{ id: 2, value: "Canberra" }, { id: 4, value: "Vienna" }] }, { journeyId: 1003, Number: "004", DriverName: "Jack", Transporter: { id: "T3", number: "AN01003", Company: "Trax" }, place: [{ id: 1, value: "Washington DC" }, { id: 4, value: "Vienna" }] }], "20180211": [{ journeyId: 1004, Number: "005", DriverName: "Jack", Transporter: { id: "T3", number: "AN01013", Company: "Trax" }, place: [{ id: 5, value: "Bridgetown" }, { id: 6, value: "Ottawa" }, { id: 4, value: "Vienna" }] }, { journeyId: 1005, Number: "005", DriverName: "Jerry", Transporter: { id: "T3", number: "AN01020", Company: "Trax" }, place: [{ id: 5, value: "Bridgetown" }, { id: 6, value: "Ottawa" }] }], "20180301": [{ journeyId: 1006, Number: "005", DriverName: "demy", Transporter: { id: "T3", number: "AN01003", Company: "Trax" }, place: [{ id: 5, value: "Bridgetown" }, { id: 6, value: "Ottawa" }] }] },
options = ["20180211", /* "Trax", */ "Vienna", "AN01020"];
console.log(filter(trips, options));
.as-console-wrapper { max-height: 100% !important; top: 0; }
One could use recursion to search for values in an object:
function hasValue(obj, values){
for(const value of Object.values(obj)){
if(typeof value === "object"){
if(hasValue(value, values))
return true;
} else {
if(values.includes(value))
return true;
}
}
return false;
}
Now we could filter your trips by comparing the keys and using the function above:
const filteredTrips = Object.keys(trips).filter(key => {
if(FilteredSelectedOptions.includes(key))
return true;
if(hasValue(trips[key], FilteredSelectedOptions))
return true;
return false;
});
Let me know if you want a complete code.
Lets begin that objects in javascript don't have built in filter or reduce methods, only arrays do. What I would do, I would loop through the object properties, which are arrays, and check if they have one of the properties that are found in the FilteredSelectedOptions. If I find one, I will push it to a new array containing the results.