I would like to know how to convert object properties string to integer in javascript.
I have a obj, which if has property value is number string convert to number in javascript
var obj={
ob1: {id: "21", width:"100",height:"100", name: "image1"},
ob2: {id: "22", width:"300",height:"200", name: "image2"}
}
function convertIntObj (obj){
Object.keys(obj).map(function(k) {
if(parseInt(obj[k])===NaN){
return obj[k]
}
else{
return parseInt(obj[k]);
}
});
}
var result = convertIntObj(obj);
console.log(result)
Expected Output:
[
{id: 21, width:100,height:100, name: "image1"},
{id: 22, width:300,height:200, name: "image2"}
]
This should do the work:
var obj = {
ob1: {
id: "21",
width: "100",
height: "100",
name: "image1"
},
ob2: {
id: "22",
width: "300",
height: "200",
name: "image2"
}
}
function convertIntObj(obj) {
const res = {}
for (const key in obj) {
res[key] = {};
for (const prop in obj[key]) {
const parsed = parseInt(obj[key][prop], 10);
res[key][prop] = isNaN(parsed) ? obj[key][prop] : parsed;
}
}
return res;
}
var result = convertIntObj(obj);
console.log('Object result', result)
var arrayResult = Object.values(result);
console.log('Array result', arrayResult)
Click "Run code snippet" so see the result
Iterating over Object.keys() twice. If the value corresponding to the key is a number then parseInt the value else set the default value which was present earlier
var obj = {
ob1: { id: "21", width: "100", height: "100", name: "image1" },
ob2: { id: "22", width: "300", height: "200", name: "image2" }
};
var res = {};
Object.keys(obj).forEach(key => {
res[key] = {};
Object.keys(obj[key]).forEach(temp => {
res[key][temp] = !isNaN(obj[key][temp])
? parseInt(obj[key][temp], 10)
: obj[key][temp];
});
return res;
});
console.log(res);
.as-console-wrapper { max-height: 100% !important; top: 0; }
You can use Object.entries() and .reduce() methods to iterate over the key value pairs in your data and use Number and Number.isNaN() methods to transform the values appropriately.
const data = {
ob1: {id: "21", width:"100",height:"100", name: "image1"},
ob2: {id: "22", width:"300",height:"200", name: "image2"}
};
const result = Object.entries(data).reduce((r, [k, o]) => {
r[k] = Object.entries(o).reduce((r, [k, v]) => {
let _v = Number(v);
if(!Number.isNaN(_v)) { v = _v; }
return (r[k] = v, r);
}, {});
return r;
}, {});
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Hi I would recommend you to use the JSON.stringify() method. It is used to convert object to string which is needed to send data over the web server. It converts the set of variables in the object to a JSON string:
var objToStr = {
siteName: "W3Docs",
bookName: "Javascript",
booksCount: 5
};
var myJSON = JSON.stringify(objToStr);
console.log(myJSON);
Also, you can use the The toString() method. It is also called when you need to convert the object into a string:
var obj = {
siteName: "W3Docs",
bookName: "Javascript",
booksCount: 5
};
function objToString(object) {
var str = '';
for (var k in object) {
if (object.hasOwnProperty(k)) {
str += k + '::' + object[k] + '\n';
This information is taken from this source.
Related
I am working on an application where I need to get combine the object of same department based on the
conditions provided in the second Array and attach the relation to the object.
let inArr1 = [{"D1D2":"AND"},{"D3D4":"OR"}]
let inArr2 =[{"ID":"1","NAME":"KEN","DEPT1":"CSE"},
{"ID":"2","NAME":"MARK","DEPT2":"IT"},
{"ID":"3","NAME":"TOM","DEPT3":"ECE"},
{"ID":"4","NAME":"SHIV","DEPT4":"LIB"},
{"ID":"5","NAME":"TIM","DEPT5":"SEC"}
]
Output
outArr ={
[{"ID":"1","NAME":"KEN","DEPT1":"CSE","REL":"AND"},
{"ID":"2","NAME":"MARK","DEPT2":"IT","REL":"AND"}], //Arr1
[{"ID":"3","NAME":"TOM","DEPT3":"ECE","REL":"OR"},
{"ID":"4","NAME":"SHIV","DEPT4":"LIB","REL":"OR"}], //Arr2
[{"ID":"5","NAME":"TIM","DEPT5":"SEC"}] //Arr3
}
Code:
let condArr=[],outArr,i=1;
inArr1.forEach(condt => {
let dept = Object.keys(condt)[0];
let tmparr = dept.split("D");
tmparr.shift()
condArr.push(tmparr)
});
inArr2.forEach(condt => {
if(condArr.includes(inArr2.D+i)){
i++;
outArr.push(inArr2);
}
});
Your code has a bit confused logic, i would suggest rather this
let inArr1 = [{"D1D2":"AND"},{"D3D4":"OR"},{"D5D6":"AND"}]
let inArr2 =[{"ID":"1","NAME":"KEN","DEPT1":"CSE"},
{"ID":"2","NAME":"MARK","DEPT2":"IT"},
{"ID":"3","NAME":"TOM","DEPT3":"ECE"},
{"ID":"4","NAME":"SHIV","DEPT4":"LIB"},
{"ID":"5","NAME":"TIM","DEPT5":"SEC"},
{"ID":"6","NAME":"TLA","DEPT6":"SEC"},
]
// first lets create object of ids as keys and conditions as values
const [keys, conditions] = inArr1.reduce((agg, cond, index) => {
Object.entries(cond).forEach(([key, value]) => {
key.split('D').forEach(v => { if (v) agg[0][v] = { value, index }})
agg[1].push([])
})
return agg
}, [{}, []]) // {1: "AND", 2: "AND", 3: "OR", 4: "OR"}
conditions.push([])
// and now just map over all elements and add condition if we found id from the keys
inArr2.forEach(item => {
const cond = keys[item.ID]
if (cond) conditions[cond.index].push({...item, REL: cond.value})
else conditions[conditions.length - 1].push(item)
})
const res = conditions.filter(v => v.length)
console.log(res)
You could store the goups by using the ID and use new objects.
let inArr1 = [{ D1D2: "AND" }, { D3D4: "OR" }],
inArr2 = [{ ID: "1", NAME: "KEN", DEPT1: "CSE" }, { ID: "2", NAME: "MARK", DEPT2: "IT" }, { ID: "3", NAME: "TOM", DEPT3: "ECE" }, { ID: "4", NAME: "SHIV", DEPT4: "LIB" }, { ID: "5", NAME: "TIM", DEPT5: "SEC" }],
groups = inArr1.reduce((r, o) => {
Object.entries(o).forEach(([k, REL]) => {
var object = { REL, group: [] };
k.match(/[^D]+/g).forEach(id => r[id] = object);
});
return r;
}, {}),
grouped = inArr2.reduce((r, o) => {
var { REL, group } = groups[o.ID] || {};
if (group) {
if (!group.length) r.push(group);
group.push(Object.assign({}, o, { REL }));
} else {
r.push([o]);
}
return r;
}, []);
console.log(grouped);
.as-console-wrapper { max-height: 100% !important; top: 0; }
can try other solution:
let inArr1 = [{ D1D2: "AND" }, { D3D4: "OR" }, { D6D7: "XOR" }];
let inArr2 = [
{ ID: "1", NAME: "KEN", DEPT1: "CSE" },
{ ID: "2", NAME: "MARK", DEPT2: "IT" },
{ ID: "3", NAME: "TOM", DEPT3: "ECE" },
{ ID: "4", NAME: "SHIV", DEPT4: "LIB" },
{ ID: "5", NAME: "TIM", DEPT5: "SEC" },
{ ID: "9", NAME: "BAR", DEPT5: "XYZ" },
{ ID: "6", NAME: "FOO", DEPT5: "XYZ" },
];
let unmatchedArr = []
let matchedArr = inArr2.reduce((acc, obj) => {
// getting index matched from inArr1 objects key
const indexMatched = getIndexMatch(obj.ID);
// creating index if not exists
if (!acc[indexMatched] && indexMatched !== null) acc[indexMatched] = [];
// if some index matched it merge current obj with DEL property with inArr1[indexMatched] key => value
return indexMatched !== null
? acc[indexMatched].push({
...obj,
DEL: inArr1[indexMatched][Object.keys(inArr1[indexMatched])[0]]
})
// pushing on unmatchedArr
: unmatchedArr.push(obj)
, acc
}, []);
function getIndexMatch(id) {
for (const [index, obj] of inArr1.entries()) {
for (const key of Object.keys(obj)) {
// spliting only digits of the current key of object
if (key.match(/\d/g).includes(id)) return index; // returning index of inArr1 if is included
}
}
return null;
}
// merging arrays
const result = [...matchedArr, unmatchedArr];
console.log(result);
I need to count each value on the object array , the desired output should be like below
[{
"question": "question1",
"USA": 2
}, {
"question": "question1",
"AUS": 1
},
{
"question": "question2",
"item1": 2
},
{
"question": "question2",
"item1,item2": 1
}, {
"question": "question4",
"3": 1
}, {
"question": "question4",
"2": 1
}
]
Below is the input I need to transform in to the above output. I have no clue how to do with n no of question and also got issue when one question has 2 answers . sample input
[{"question1":"USA","question2":["item1"],"question4":2},
{"question1":"USA","question2":["item1"],"question4":3},
{"question1":"AUS","question2":["item1","item2"]}];
let arr=[{"question1":"USA","question2":["item1"],"question4":2},{"question1":"USA","question2":["item1"],"question4":3},{"question1":"AUS","question2":["item1","item2"]}];
//console.log(arr);
function solve(list){
var map = new Map();
var entry = null;
for(var item of list){
if(!map.has(item.question1))
map.set(item.question1, {question:'question1'});
entry = map.get(item.question1);
if(entry.hasOwnProperty(item.question1))
entry[item.question1] = entry[item.question1] + 1;
else
entry[item.question1] = 1;
if(!map.has(item.question2))
map.set(item.question2, {question: 'question2'});
entry = map.get(item.question2);
if(entry.hasOwnProperty(item.question2))
entry[item.question2] = entry[item.question2] + 1;
else
entry[item.question2] = 1;
}
return Array.from(map.values());
}
console.log(solve(arr))
You could take an object or what ever data structure you like which supports a key/value structure in a nested style and collect first all items and then reder the collected tree.
This approach uses objects, because the keys are strings, this is important for an array as key. This is joint with a comma which is sufficient for this use case.
var data = [{ question1: "USA", question2: ["item1"], question4: 2 }, { question1: "USA", question2: ["item1"], question4: 3 }, { question1: "AUS", question2: ["item1", "item2"] }],
hash = data.reduce((hash, o) => {
Object.entries(o).forEach(([question, value]) => {
var sub = hash[question] = hash[question] || Object.create(null);
sub[value] = sub[value] || { question, [value]: 0 };
sub[value][value]++;
});
return hash;
}, Object.create(null)),
result = Object.values(hash).reduce((r, sub) => [...r, ...Object.values(sub)], []);
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
First, obtain the countries by using reduce. Then use some nested forEach loops for the rest:
const input = [{"question1":"USA","question2":["item1"],"question4":2},
{"question1":"USA","question2":["item1"],"question4":3},
{"question1":"AUS","question2":["item1","item2"]}];
const countriesOutput = input.reduce((acc, curr) => {
if (!acc.some(e => e[curr.question1])) {
acc.push({ question: "question1", [curr.question1]: 1 });
} else {
acc.find(e => e[curr.question1])[curr.question1]++;
}
return acc;
}, []);
let questionsOutput = [];
input.forEach(item => {
Object.keys(item).forEach(key => {
if (key != "question1") {
if (Array.isArray(item[key])) {
questionsOutput.push({ question: key, [item[key].join(",")]: 1 });
} else {
questionsOutput.push({ question: key, [item[key]]: 1 });
}
}
});
});
const finalOutput = [...countriesOutput, ...questionsOutput];
console.log(finalOutput);
.as-console-wrapper { max-height: 100% !important; top: auto; }
Its a matter of summarizing the input using a dictionary (like Object) and track the duplicates. The "name" of the name/value pair can be uniquely identified by combining the question and answer with some delimiter.
const input = [{
"question1": "USA",
"question2": ["item1"],
"question4": 2
},
{
"question1": "USA",
"question2": ["item1"],
"question4": 3
},
{
"question1": "AUS",
"question2": ["item1", "item2"]
}
];
//Sum the input to an array which we can easily search for duplciates
var repeatCounter = {};
input.forEach(objItem => {
Object.keys(objItem).forEach(propItem => {
//Get the counter and the string
var s = `${propItem}-${objItem[propItem]}`;
var c = repeatCounter[s] || 0;
//Modify it or introduce it if absent
repeatCounter[s] = c + 1;
})
})
var output = Object.keys(repeatCounter).map(element => {
var ret = {'question': element.split('-')[0]}
ret[element.split('-')[1]] = repeatCounter[element];
return ret;
})
console.log(output);
.as-console-wrapper {
max-height: 100% !important;
}
Subtle adjustments such as fortifying the delimiter, converting multiple strings in to array items(as shown in the question) needs to be done on practical grounds.
I want to convert all data into one object,
let d = {
"Coupon_Code": "code",
"Coupon_Name": "namie",
"Coupon_Desc": 1000,
"selectedCity": [
{
"Coupon_City_Name": "xyz"
}
],
"selectedCategory": [
{
"Coupon_Category_Name": "Shopping"
}
],
"selectedCompany": [
{
"Coupon_Company_Name": "Shopper Stop"
}
],
"selectedState": [
{
"Coupon_State_Name": "abc"
}
],
"Coupon_Date": "2222-02-22",
}
i tried some methods of Object like keys , entries but dont no what to use.
Final output should be
let d = {
Coupon_Code: "code",
Coupon_Name: "namie",
Coupon_Desc: 1000,
Coupon_City_Name: "xyz",
Coupon_Category_Name: "Shopping",
Coupon_Company_Name: "Shopper Stop",
Coupon_State_Name: "abc",
Coupon_Date: "2222-02-22",
};
what's the best and optimum way to have above result using Venila Js and Es6
Reduce the entries of the original object. If the entry's value is an array merge the 1st element, if not merge the original key and value. You can merge the properties into the object using object spread:
const data = {"Coupon_Code":"code","Coupon_Name":"namie","Coupon_Desc":1000,"selectedCity":[{"Coupon_City_Name":"xyz"}],"selectedCategory":[{"Coupon_Category_Name":"Shopping"}],"selectedCompany":[{"Coupon_Company_Name":"Shopper Stop"}],"selectedState":[{"Coupon_State_Name":"abc"}],"Coupon_Date":"2222-02-22"};
const result = Object.entries(data)
.reduce((r, [k, v]) => ({
...r,
...Array.isArray(v) ? v[0] : { [k]: v }
}), {});
console.log(result);
You can use Array.reduce and Object.entries
let d = {"Coupon_Code":"code","Coupon_Name":"namie","Coupon_Desc":1000,"selectedCity":[{"Coupon_City_Name":"xyz"}],"selectedCategory":[{"Coupon_Category_Name":"Shopping"}],"selectedCompany":[{"Coupon_Company_Name":"Shopper Stop"}],"selectedState":[{"Coupon_State_Name":"abc"}],"Coupon_Date":"2222-02-22"};
d = Object.entries(d).reduce((a,[k,v]) => {
// If the value is an array, iterate over it to merge into the resultant object
if(Array.isArray(v)) Object.assign(a, ...v)
else Object.assign(a, {[k]:v}) // if it is not an array, merge into resultant object
return a;
}, {});
console.log(d);
You could take a recursive approach.
const
fn = o => Object.assign(...Object.entries(o).map(([k, v]) => Array.isArray(v) ? Object.assign(...v.map(fn)) : { [k]: v })),
d = { Coupon_Code: "code", Coupon_Name: "namie", Coupon_Desc: 1000, selectedCity: [{ Coupon_City_Name: "xyz" }], selectedCategory: [{ Coupon_Category_Name: "Shopping" }], selectedCompany: [{ Coupon_Company_Name: "Shopper Stop" }], selectedState: [{ Coupon_State_Name: "abc" }], Coupon_Date: "2222-02-22" },
result = fn(d);
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
A possible iterative solution is:
function flatten(obj) {
let r = {}
for (let [key, value] of Object.entries(obj)) {
if (Array.isArray(value)) {
Object.assign(r, value[0]);
} else {
Object.assign(r, {[key]: value});
}
}
return r;
}
Something like this:
const d = { Coupon_Code: "code", Coupon_Name: "namie", Coupon_Desc: 1000, selectedCity: [{ Coupon_City_Name: "xyz" }], selectedCategory: [{ Coupon_Category_Name: "Shopping" }], selectedCompany: [{ Coupon_Company_Name: "Shopper Stop" }], selectedState: [{ Coupon_State_Name: "abc" }], Coupon_Date: "2222-02-22" };
function toSingleObj(obj) {
var result = {};
Object.entries(obj).forEach(([key,value]) => {
if (Array.isArray(value)) {
Object.entries(value[0]).forEach(([k,v]) => {
result[k] = v;
});
} else {
result[key] = value;
}
});
return result;
}
console.log("Result: ", toSingleObj(d));
I have an array like,
0: "City1"
1: {name="sds", age="asd",....}
2: {name="sweds", age="accxsd",....}
3: {name="sdqws", age="asssd",....}
4: "City2"
... and many more
So I need to get the elements between index[0] and index[4],
Am able to check the string and object using typeof
for(i=0; i<=arr.length; i++){
if(typeof arr[i] == 'string'){
... // need to find next element eith type string
}
}
Is there a way to find the next element in an array whose value is string, so I can get elements between them.
You can use this alternative using the function reduce.
This approach builds an object grouping the objects into an array with the found string value.
var array = [ "City1", {name:"sds", age:"asd"}, {name:"sweds", age:"accxsd"}, {name:"sdqws", age:"asssd"}, "City2", {name:"sds2", age:"asd2"}, {name:"sweds2", age:"accxsd2"}, {name:"sdqws2", age:"asssd2"}];
var result = array.reduce((a, c) => {
if (typeof c === 'string') {
a[c] = [];
a.current = c;
} else if (a.current !== "") {
a[a.current].push(c);
}
return a;
}, {current: ""});
delete result.current;
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
How can I adjust to a particular String value, like if my input id 'city3', I need to get all elements between 'city3' and its next string value
The above approach groups the elements by the previously found string element, so you can directly access the desired target City3
var array = [ "City1", {name:"sds", age:"asd"}, {name:"sweds", age:"accxsd"}, {name:"sdqws", age:"asssd"}, "City3", {name:"sds3", age:"asd3"}, {name:"sweds3", age:"accxsd3"}, {name:"sdqws3", age:"asssd3"}, "City4", {name:"sds4", age:"asd4"}, {name:"sweds4", age:"accxsd4"}, {name:"sdqws4", age:"asssd"}];
var result = array.reduce((a, c) => {
if (typeof c === 'string') {
a[c] = [];
a.current = c;
} else if (a.current !== "") {
a[a.current].push(c);
}
return a;
}, {
current: ""
});
delete result.current;
var target = "City3";
// Now you have a direct access to find the desired target.
console.log(result[target]);
.as-console-wrapper { max-height: 100% !important; top: 0; }
You can just filter your array:
var arr = [
"City1",
{name:"sds", age:"asd"},
{name:"sweds", age:"accxsd"},
{name:"sdqws", age:"asssd"},
"City2"
];
var res = arr.filter(e => typeof e !== 'string');
console.log(res);
EDIT: if you want result from a specified start string, it should be:
var arr = [
"City1",
{name:"sds1", age:"asd"},
{name:"sweds1", age:"accxsd"},
{name:"sdqws1", age:"asssd"},
"City2",
{name:"sds2", age:"asd"},
{name:"sweds2", age:"accxsd"},
{name:"sdqws2", age:"asssd"},
"City3"
];
var str = 'City2';
var start = arr.indexOf(str);
var end = arr.findIndex((s, i) => typeof s === 'string' && i > start);
var res = arr.filter((e, i) => i > start && i < end);
console.log(res);
You could take a flag for filtering.
If a string is found switch the filter flag by checking the value with the wanted group 'City3'.
var array = ["City1", { name: "city1", age: 22 }, { name: "city1", age: 23 }, "City2", { name: "city2", age: 22 }, { name: "city2", age: 23 }, "City3", { name: "city3", age: 21 }, { name: "city3", age: 22 }, { name: "city3", age: 23 }, "City4", { name: "city4", age: 23 }, "City5"],
group = 'City3';
result = array.filter(
(f => v => typeof v === 'string' ? (f = v === group, false) : f)(false)
);
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Using a traditional for...loop you can use continue in the loop to progress to the next index if your condition is a match:
const data = [
"City1",
{ name:"sds", age: "asd" },
{ name: "sweds", age: "accxsd" },
{ name: "sdqws", age: "asssd" },
"City2"
]
for (let i = 0; i < data.length; i++) {
if (typeof data[i] === 'string') continue;
console.log(data[i].name)
}
In this stackoverflow thread, i learnt you can get a object path via a simple string.
Accessing nested JavaScript objects with string key
consider the following:
var person = { name: "somename", personal: { weight: "150", color: "dark" }};
var personWeight = deep_value(person,"personal.weight");
I an trying to construct an array of the object values who are not of type 'object' from my 'person' object.
Hence the array would look like:
[['name', []],['personal.weight', []],['personal.color', []]];
I want them to look in that form because i have further use for it down the road.
That's what I've tried:
var toIterate = { name: "somename", personal: { age: "19", color: "dark" } }
var myArray = [];
$.each(toIterate, recursive);
function recursive(key, value) {
if (key !== null) {
myArray.push([key, []]);
}
else {
$.each(value, recursive);
}
}
console.log(myArray);
Just use recursion to walk the object.
var person = {
name: "somename",
personal: {
weight: "150",
color: "dark",
foo: {
bar: 'bar',
baz: 'baz'
},
empty: {
}
}
};
// however you want to do this
var isobject = function(x){
return Object.prototype.toString.call(x) === '[object Object]';
};
var getkeys = function(obj, prefix){
var keys = Object.keys(obj);
prefix = prefix ? prefix + '.' : '';
return keys.reduce(function(result, key){
if(isobject(obj[key])){
result = result.concat(getkeys(obj[key], prefix + key));
}else{
result.push(prefix + key);
}
return result;
}, []);
};
var keys = getkeys(person);
document.body.innerHTML = '<pre>' + JSON.stringify(keys) + '</pre>';
Then use Array.prototype.map to massage the array of keys into your preferred format.
Note the behaviour with person.personal.empty.
This does seem like a strange way to store an object's keys. I wonder what your 'further use for it down the road' is.
This is what worked for me. Note that, a raw map is created first and then mapped to an join the items in the Array with ..
var toIterate = {
name: "somename",
personal: {
age: "19",
color: "dark"
}
};
console.log(getObjPath(toIterate).map(item => item.join('.')));
function isObject(x) {
return Object.prototype.toString.call(x) === '[object Object]';
};
function getObjPath(obj, pathArray, busArray) {
pathArray = pathArray ? pathArray : [];
if (isObject(obj)) {
for (key in obj) {
if (obj.hasOwnProperty(key)) {
if (isObject(obj[key])) {
busArray = busArray ? bussArray : [];
busArray.push(key);
getObjPath(obj[key], pathArray, busArray);
} else {
if (busArray) {
pathArray.push(busArray.concat([key]));
} else {
pathArray.push([key]);
}
}
}
}
}
return pathArray;
}
Good Luck...
I found the following solution on github.
https://github.com/mariocasciaro/object-path