I have the following JavaScript object. I need to generate a new object from the given object. What is the approach I should take in JavaScript?
[
{"name": "Dan", "city" : "Columbus", "ZIP":"47201"},
{"name": "Jen", "city" : "Columbus", "ZIP":"47201"},
{"name": "Mark", "city" : "Tampa", "ZIP":"33602"},
]
How can I transform or pivot to generate the following object?
[
{ "47201": [
{"name": "Dan", "city": "Columbus"},
{"name": "Jen", "city": "Columbus"},
],
"count": "2"
},
{ "33602": [
{"name": "Mark", "city": "Tampa"}
],
"count": "1"
}
]
I don't know why you want the .count property, when that can be accessed via the array's .length property, but anyway:
const input = [
{"name": "Dan", "city" : "Columbus", "ZIP":"47201"},
{"name": "Jen", "city" : "Columbus", "ZIP":"47201"},
{"name": "Mark", "city" : "Tampa", "ZIP":"33602"},
]
const working = input.reduce((acc, {ZIP, name, city}) => {
(acc[ZIP] || (acc[ZIP] = [])).push({name, city})
return acc
}, {})
const output = Object.keys(working)
.map(k => ({[k]: working[k], count: working[k].length}))
console.log(output)
Further reading:
Array .reduce()
Array .map()
Object.keys()
Unpacking fields from objects passed as function parameters
Computed property names
The below code will work for your requirement. The final result is stored in the variable result which holds the array object.
var source = [{
"name": "Dan",
"city": "Columbus",
"ZIP": "47201"
},
{
"name": "Mark",
"city": "Tampa",
"ZIP": "33602"
},
{
"name": "Jen",
"city": "Columbus",
"ZIP": "47201"
}
];
var result = [];
finalarr('ZIP');
function finalarr(propname) {
var obj = JSON.parse(JSON.stringify(source));
obj.forEach(function(elm,i) {
var arr = {};var chli=[];var charr={};
var flag = 0;
for (var prop in elm) {
if(prop != propname){
charr[prop]=elm[prop];
}
}
for(var i=0;i<result.length;i++){
if(result[i][elm[propname]]){
result[0][elm[propname]].push(charr);
//console.log(result[i][propname]);
flag = 1;
}
}
if(flag == 0){
chli.push(charr);
arr["count"] = checkarr(obj,propname,elm[propname]);
arr[elm[propname]]=chli;
result.push(arr);
}
});
}
function checkarr(obj,propname,value){
var count = 0;
obj.forEach(function(elm,i) {
if(elm[propname] == value){
count++;
}
});
return count;
}
console.log(result);
Related
How can we push values to an object from inside a map function and return that single object. I have string comparison condition inside the map function. I tried using Object.assign but it returns an array with multiple object inside that array. Instead of this multiple object I'm expecting a single object inside an array.
Map function
let arrayObj = arrayToTraverse.map(function(item) {
var myObj = {};
if(item.inputvalue === 'Name'){
Object.assign(myObj, {name: item.value});
} else if (item.inputvalue === 'Email'){
Object.assign(organizerInfo, {email: item.value});
} else if (item.inputvalue === 'Company'){
Object.assign(organizerInfo, {company: item.value});
}
return myObj;
});
console.log("The array object is", arrayObj)
This return the array of objects as follows
[
{
"name": "Tom"
},
{
"email": "tom#abc.com"
},
{
"company": "ABC"
}
]
But The array I'm expecting is
[
{
"name": "Tom",
"email": "tom#abc.com",
"company": "ABC"
}
]
// or
[
"returned": {
"name": "Tom",
"email": "tom#abc.com",
"company": "ABC"
}
]
An example of arrayToTraverse can be considered as following
[
{
"id": "1",
"inputvalue": "Name",
"value": "Tom",
"type": "Short Text"
},
{
"id": "2",
"inputvalue": "Email",
"value": "tom#abc.com",
"type": "Email ID"
},
{
"id": "3",
"inputvalue": "Company",
"value": "Google",
"type": "Long Text"
}
]
Simply put, you're trying to reduce an array to a single object, not map one array to another.
var arrayToTraverse = [
{inputvalue:"Name",value:"Tom"},
{inputvalue:"Email",value:"tom#abc.com"},
{inputvalue:"Company",value:"ABC"},
{inputvalue:"Foo",value:"Bar"} // wont show up
];
var valuesRequired = ["Name","Email","Company"];
var result = arrayToTraverse.reduce( (acc, item) => {
if(valuesRequired.includes(item.inputvalue))
acc[item.inputvalue.toLowerCase()] = item.value;
return acc;
}, {});
console.log(result);
Edit: Added lookup array for required fields.
I have an array of objects and want to filter it based on values of another string array and remove the objects that doesn't contain any of the strings.
I tried using split for the string array and search for each term in a forEach but it didn't work then tried the following which works as a filter but it filters for exact match not partial.
var employees = [
{"name": "zxc asd", "age":"30"},
{"name": "asd", "age":"24"},
{"name": "qwe", "age":"44"},
{"name": "zxc", "age":"28"},
];
var keepNames = ["asd", "qwe"];
keepNames = keepNames.map(name => {
return name.toLowerCase();
});
var filteredEmployees = employees.filter(emp => {
return keepNames.indexOf(emp.name.toLowerCase()) !== -1;
});
console.log( filteredEmployees );
Expected Output[
{"name": "zxc asd", "age":"30"},
{"name": "asd", "age":"24"},
{"name": "qwe", "age":"44"}];
Actual Output [
{"name": "asd", "age":"24"},
{"name": "qwe", "age":"44"}]
I'd really appreciate any help.
Thanks in advance
You need to iterate the array with names keep as well and check the value.
var employees = [{ name: "zxc asd", age: "30" }, { name: "asd", age: "24" }, { name: "qwe", age: "44" }, { name: "zxc", age: "28" }],
keep = ["asd", "qwe"],
filtered = employees.filter(({ name }) =>
keep.some(n => name.toLowerCase().includes(n))
);
console.log(filtered);
.as-console-wrapper { max-height: 100% !important; top: 0; }
indexOf uses strict equality so it won't match partially.
You can use some and includes
var employees = [ {"name": "zxc asd", "age":"30"},{"name": "asd", "age":"24"},{"name": "qwe", "age":"44"},{"name": "zxc", "age":"28"},];
var filterBy = ["asd", "qwe"];
var filteredEmployees = employees.filter(emp => {
return filterBy.some(v => emp.name.toLowerCase().includes(v.toLowerCase()))
});
console.log(filteredEmployees);
I have this object with nested arrays/objects:
{
"USA": [
{
"location": "New York",
"municipality": "Manhattan",
},
{
"location": "Texas",
"municipality": "Austin",
}
],
"CANADA": [
{
"location": "Ontario",
"municipality": "no municipality",
}
]
}
I want to use lodash or plain javascript to count how many location are inside the USA and CANADA. How is that possible?
desired result:
USA: 2
CANADA: 1
Just use the array lengths:
var USA = myObj.USA.length;
var Canada = myObj.CANADA.length;
Or, for larger data sets:
var result = {};
Object.keys(myObj)
.forEach(function(key,index) {
result[key] = myObj[key].length;
});
With lodash you could use mapValues:
let result = _.mapValues(data, 'length');
The solution using Array.prototype.reduce() function:
var obj = {
"USA": [ { "location": "New York", "municipality": "Manhattan" }, { "location": "Texas", "municipality": "Austin" } ], "CANADA": [ { "location": "Ontario", "municipality": "no municipality" }]
},
result = Object.keys(obj).reduce(function(r,k){
r[k] = obj[k].length;
return r;
}, {});
console.log(result)
i'm searching a smart way to reoganise an array by a element inside it:
In entry i've got:
[{"name": "brevet",
"country": "fr"
},{
"name": "bac",
"country": "fr"
},{
"name": "des",
"country": "ca"
},{
"name": "dep",
"country": "ca"
}{
"name": "other",,
"country": "other"}]
I want to reorganize my array by country to have this in my output:
[{
"name": "fr",
"degrees": [
{
"name": "brevet",
"country": "fr"
},{
"name": "bac",
"country": "fr"
}]
},{
"name": "ca",
"degrees": [{
"name": "des",
"country": "ca"
},{
"name": "dep",
"country": "ca"
}]
},{
"name": "other",
"degrees": [{
"name": "other",
"country": "other"
}]
}]
For this i write a dirty function, but it seems to me there is a better way but i don't see how. If someone can ligth my brain in a better way to do this i'll be helpfull
private organizeDegrees(degrees: Array<SubscriptionFieldInterface>) {
let degreesByCountry = new Array();
let storeIndex = new Array();
degrees.map(degree => {
let index = null;
storeIndex.find((element, idx) => {
if (element === degree.country) {
index = idx;
return true;
}
});
if (index === null) {
index = degreesByCountry.length;
let newEntry = {
'name': degree.country,
'degrees': new Array()
};
storeIndex.push(degree.country);
degreesByCountry.push(newEntry);
}
degreesByCountry[index].degrees.push(degree);
});
return degreesByCountry;
}
thank's
You can group the array and map the object using Object.keys:
var groupBy = function(xs, key) {
return xs.reduce(function(rv, x) {
(rv[x[key]] = rv[x[key]] || []).push(x);
return rv;
}, {});
};
var grouped = groupBy(array, "country");
var mappedArray = Object.keys(grouped).map(key => ( {name: key, degrees: grouped [key]} ));
And one more way:
arr = [ /* your array */ ];
arr = Object.values(arr.reduce((ac, el) => {
if(!ac[el.country]) ac[el.country] = {"name": el.country, "degrees": []}
ac[el.country].degrees.push(el);
return ac
}, {}))
console.log(arr) // formated
Another solution, which also handles 'id' => '#id' mapping:
const a = [{"name":"brevet","country":"fr"},{"name":"bac","country":"fr"},{"id":73,"name":"des","country":"ca"},{"name":"dep","country":"ca"},{"name":"other","country":"other"}];
const r = [...new Set(a.map(({country}) => country))] // list of unique country names
.map(c => Object.assign({name: c}, // for each country
{degrees: a.filter(x => x.country === c).map(y => Object.keys(y).includes('id') // handle 'id' => '#id' mutation
? {'#id': "/subscription_fields/" + y.id, name: y.name, country: y.country}
: y)
}))
console.log(r)
This is purely ES6, and quite terse, but possibly less readable. Also, it doesn't add the "#id": "/subscription_fields/83", which could be added as a post process:
const groupByKey = (arr, key) => [...arr.reduce((acc, deg) =>
acc.set(deg[key], {name: deg[key], degrees: [ ...(acc.get(deg[key]) || {degrees: []}).degrees, deg]})
, new Map()).values()];
console.log(groupByKey(degrees, 'country'));
You could use a hash table and collect all values in an object. For getting the result array, you need to push the object only once.
var data = [{ name: "brevet", country: "fr" }, { name: "bac", country: "fr" }, { id: 73, name: "des", country: "ca" }, { name: "dep", country: "ca" }, { name: "other", country: "other" }],
result = data.reduce(function (hash) {
return function (r, a) {
if (!hash[a.country]) {
hash[a.country] = { name: a.country, degrees: [] };
r.push(hash[a.country]);
}
hash[a.country].degrees.push({ name: a.name, country: a.country });
return r;
};
}(Object.create(null)), []);
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
I have some data which looks like this:
{
"obj":
[
{
"name": "name1",
"age": "24"
},
{
"name": "name2",
"age": "17"
}
]
}
What I need to do is to create 2 arrays from it.
For example:
namelist[];
agelist[];
so the result would be:
namelist: ['name1', 'name2'];
agelist: [24, 17];
My question is, how can I do this?
var namelist = [];
var agelist = [];
for(var i in obj.obj){
namelist.push(obj.obj[i].name);
agelist.push(obj.obj[i].age);
}
console.log(namelist, agelist);
Is this what U wanted ?
var zz={
"obj": [
{
"name": "name1",
"age": "24"
},
{
"name": "name2",
"age": "17"
}
]
}
namelist=[];
agelist=[];
zz.obj.forEach(function(rec){
namelist.push(rec.name);
agelist.push(rec.age);
})
console.log(namelist,agelist)
You could use this ES6 code, and use the unitary plus for getting the ages as numbers. Assuming your object is stored in variable data:
var namelist = data.obj.map( o => o.name );
var agelist = data.obj.map( o => +o.age );
var data = {
"obj": [
{
"name": "name1",
"age": "24"
},
{
"name": "name2",
"age": "17"
}
]
};
var namelist = data.obj.map( o => o.name );
var agelist = data.obj.map( o => +o.age );
console.log(namelist);
console.log(agelist);
var arr = $.map(myObj, function(value, index) {
return [value];
});
console.log(arr);
if you are not using Jquery then:
var arr = Object.keys(myObj).map(function (key)
{ return obj[key];
});`
Make use of jquery map function or otherwise you can loop over the object and push it into array using javascript for loop and use the push() function. Refer Loop through an array in JavaScript
Jquery
var data = {
"obj": [
{
"name": "name1",
"age": "24"
},
{
"name": "name2",
"age": "17"
}
]
}
var name = $.map(data.obj, function(value, index) {
return value.name;
});
var age = $.map(data.obj, function(value, index) {
return value.age;
});
console.log(name);
console.log(age);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
Javascript
var data = {
"obj": [
{
"name": "name1",
"age": "24"
},
{
"name": "name2",
"age": "17"
}
]
}
var names = [], ages=[];
data.obj.forEach(function(value, index) {
names.push(value.name);
ages.push(value.age);
});
console.log(names,ages);