I am trying to traverse the data according to the show array and print the data to see if it is correct. To traverse the list array corresponding to the show array as follows
I want the effect as follows:
[
{
"name": "A",
"age": "10",
},
{
"name": "B",
"age": "20",
}
]
const data = [{
"code": "200",
"msg": "success",
"data": {
"list": [{
"name": "A",
"age": "10",
"logo": "aa.png",
"note": "aa"
}, {
"name": "B",
"age": "20",
"logo": "bb.png",
"note": "bb"
}],
"show": [
"name",
"age"
]
}
}]
function init() {
data.map(res => {
if (res.code == 200) {
console.log(res.data.list)
}
})
}
init();
By iterating show (rather than hard-coding name and age), this code would work also if you change the structure of your template:
const data = [{
"code": "200",
"msg": "success",
"data": {
"list": [{
"name": "A",
"age": "10",
"logo": "aa.png",
"note": "aa"
}, {
"name": "B",
"age": "20",
"logo": "bb.png",
"note": "bb"
}],
"show": [
"name",
"age"
]
}
}];
var ans = data[0].data.list.map(item => {
var curr = {};
data[0].data.show.forEach(prop => {
curr[prop] = item[prop];
});
return curr;
});
console.log(ans);
You can use reduce in a shorter way:
const data = [
{
code: "200",
msg: "success",
data: {
list: [
{
name: "A",
age: "10",
logo: "aa.png",
note: "aa"
},
{
name: "B",
age: "20",
logo: "bb.png",
note: "bb"
}
],
show: ["name", "age"]
}
}
];
console.log(data[0].data.list.map(x =>
data[0].data.show.reduce((p, c) => ((p[c] = x[c]), p), {})
));
const data = [{
"code": "200",
"msg": "success",
"data": {
"list": [{
"name": "A",
"age": "10",
"logo": "aa.png",
"note": "aa"
}, {
"name": "B",
"age": "20",
"logo": "bb.png",
"note": "bb"
}],
"show": [
"name",
"age"
]
}
}];
function init() {
data.map(res => {
if (res.code == 200) {
console.log(res.data.list.map(function(listValue) {
var ret = {};
res.data.show.forEach(function(idx) {
ret[idx] = listValue[idx]
});
return ret;
}));
}
})
}
init();
You can use .map on your data and return false if the code isn't 200, if it is 200, you can return a mapped version of your list array. You can map this array to a subset of each object in your list. The subset is defined by your show array, and so you can use .reduce() on this array to build your mapped object.
See example below:
const data = [{
"code": "200",
"msg": "success",
"data": {
"list": [{
"name": "A",
"age": "10",
"logo": "aa.png",
"note": "aa"
}, {
"name": "B",
"age": "20",
"logo": "bb.png",
"note": "bb"
}],
"show": [
"name",
"age"
]
}
}];
function init() {
return data.map(res => {
if (res.code == 200) {
return res.data.list.map((obj) => {
return res.data.show.reduce((acc, prop) => ({...acc, [prop]: obj[prop]}), {});
});
}
return false;
}).filter(Boolean); // filter out any `false` returns
}
console.log(init());
Alternatively, a better approach than mapping your original data would be to use .reduce(). This will create a one-dimensional array of results:
const data = [{
"code": "200",
"msg": "success",
"data": {
"list": [{
"name": "A",
"age": "10",
"logo": "aa.png",
"note": "aa"
}, {
"name": "B",
"age": "20",
"logo": "bb.png",
"note": "bb"
}],
"show": [
"name",
"age"
]
}
},
{
"code": "200",
"msg": "success",
"data": {
"list": [{
"name": "C",
"age": "30",
"logo": "aa.png",
"note": "aa"
}, {
"name": "D",
"age": "40",
"logo": "bb.png",
"note": "bb"
}],
"show": [
"name",
"age"
]
}
}];
function init() {
return data.reduce((acc, res) => {
if (res.code == 200) {
return [...acc, ...res.data.list.map((obj) => {
return res.data.show.reduce((acc, prop) => ({...acc, [prop]: obj[prop]}), {});
})];
}
return acc;
}, []);
}
console.log(init());
If you want to show only name and age as
[
{
"name": "A",
"age": "10",
},
{
"name": "B",
"age": "20",
}
]
Array.map can be used
and then you can write your code this way
const data = [
{
code: '200',
msg: 'success',
data: {
list: [
{
name: 'A',
age: '10',
logo: 'aa.png',
note: 'aa'
},
{
name: 'B',
age: '20',
logo: 'bb.png',
note: 'bb'
}
],
show: ['name', 'age']
}
}
]
function init() {
data.map(res => {
if (res.code == 200) {
console.log(
res.data.list.map(item => {
return {
name: item.name,
age: item.age
}
})
)
}
})
}
init()
Does this answer your question?
Related
I need to find value of type2.id where id is 7 in the following object
[
{
"type1": {
"id": "1",
"value": "val1"
},
"type2": [
{
"id": "2",
"value": "val2"
}
]
},
{
"type1": null,
"type2": [
{
"id": "5",
"value": "val5"
}
]
},
{
"type1": {
"id": "3",
"value": "val3"
},
"type2": [
]
},
{
"type1": {
"id": "4",
"value": "val4"
},
"type2": [
{
"id": "7",
"value": "val7"
}
]
}
]
Please notice type1 is a simple object and type 2 is an array here, there can be empty array in type2 as well.
arr.find(({type2}) => type2[0]?.id === '7')?.type2[0].value
let value = null;
// First way using forEach
obj.forEach(item => {
if (item.type2 && item.type2.length > 0) {
item.type2.forEach(type2 => {
if (type2.id === '7') {
value = type2.value;
}
});
}
});
console.log("first way : ", value);
// Second way using map and filter
let type2Array = obj.map(obj => obj.type2).flat()
value = type2Array.filter(obj => obj.id === '7').at(0)?.value
console.log("second way : ", value);
<script>
const obj = [{
"type1": {
"id": "1",
"value": "val1"
},
"type2": [{
"id": "2",
"value": "val2"
}]
},
{
"type1": null,
"type2": [{
"id": "5",
"value": "val5"
}]
},
{
"type1": {
"id": "3",
"value": "val3"
},
"type2": [
]
},
{
"type1": {
"id": "4",
"value": "val4"
},
"type2": [{
"id": "7",
"value": "val7"
}]
}
];
</script>
Try this
const data = [
{
type1: {
id: "1",
value: "val1",
},
type2: [
{
id: "2",
value: "val2",
},
],
},
{
type1: null,
type2: [
{
id: "5",
value: "val5",
},
],
},
{
type1: {
id: "3",
value: "val3",
},
type2: [],
},
{
type1: {
id: "4",
value: "val4",
},
type2: [
{
id: "7",
value: "val7",
},
],
},
];
const result = data.find((object) => {
const { type2 } = object;
if (!type2) {
return false;
}
const [ firstFromType2 ] = type2;
if (!firstFromType2) {
return false;
}
return firstFromType2.id === '7';
});
console.log(result);
const data = [{"type1":{"id":"1","value":"val1"},"type2":[{"id":"2","value":"val2"}]},{"type1":null,"type2":[{"id":"5","value":"val5"}]},{"type1":{"id":"3","value":"val3"},"type2":[]},{"type1":{"id":"4","value":"val4"},"type2":[{"id":"7","value":"val7"}]}]
console.log(data.flatMap(i=>i.type2).find(({id})=>id==='7')?.value)
Assign the array to a const and make a nested map.
const foundObj = array.map(obj => obj.type2.map(type2obj => type2obj.id === '7')));
const value = foundObj.value
fiddle here: https://jsfiddle.net/
Sample Input:
[
{
"id": "p1",
"top": 130,
"left": 298,
"Key": "test1",
"Next": "special"
},
{
"id": "p2",
"Key": "special",
"specialkey": [
{"key": "1", "value": "p3"},
{"key": "0", "value": "p4"},
{"key": "2", "value": "p5"}
],
"Next": "",
"RepeatText": "p8",
"RepeatTextNew": "p9",
},
{
"id": "p3",
"user": "aa",
"Key": "test3",
"Text": "hi"
},
{
"id": "p4",
"Key": "special",
"specialkey": [
{"key": "1", "value": "p6"},
{"key": "0", "value": "p7"}
]
},
{
"id": "p5",
"user": "aa",
"Key": "test5",
"Text": "hi"
},
{
"id": "p6",
"user": "aa",
"Key": "test6",
"Text": "hi"
},
{
"id": "p7",
"user": "aa",
"Key": "test7",
"Text": "hi"
},
{
"id": "p8",
"user": "aa",
"Key": "test8",
"Text": "hi"
},
{
"id": "p9",
"user": "aa",
"Key": "test9",
"Text": "hi"
}
]
Sample Output:
{
"test1": {
"id": "p1",
"top": 130,
"left": 298,
"Key": "test1",
"Next": {
"special": {
"id": "p2",
"Key": "special",
"Next": "",
"RepeatText": {
"p8": {
"id": "p8",
"user": "aa",
"Key": "test8",
"Text": "hi"
}
},
"RepeatTextNew": {
"p9": {
"id": "p9",
"user": "aa",
"Key": "test9",
"Text": "hi"
}
},
"specialkey": [
{
"key": "1",
"value": {
"id": "p3",
"user": "aa",
"Key": "test3",
"Text": "hi"
}
},
{
"key": "0",
"value": {
"id": "p4",
"Key": "special",
"specialkey": [
{
"key": "1",
"value": {
"id": "p6",
"user": "aa",
"Key": "test6",
"Text": "hi"
}
},
{
"key": "0",
"value": {
"id": "p7",
"user": "aa",
"Key": "test7",
"Text": "hi"
}
}
]
}
},
{
"key": "2",
"value": {
"id": "p5",
"user": "aa",
"Key": "test5",
"Text": "hi"
}
}
]
}
}
}
}
When the key is equal to special it can have a nested structure and for either we just need to match with the next key
With the below code, I am not able to achieve the expected output.
const processObject = ({ Next, ...rest }) => {
const result = { ...rest };
if (formatData.find((y) => y.Key == 'special')) {
const nextObject = formatData.find((y) => y.Key == 'special')
if (nextObject.specialkey) {
for (let i = 0; i < nextObject.specialkey.length; i++) {
let currentObject = formatData.find((y) => y.id === nextObject.specialkey[i].value)
nextObject.specialkey[i].value = currentObject
}
result.Next = {
[nextObject.Key]: processObject(nextObject),
};
}
}
if (Next) {
const nextObject = formatData.find((y) => y.id === Next);
result.Next = {
[nextObject.Key]: processObject(nextObject),
};
}
return result;
};
const response = {
[formatData[0].Key]: processObject(formatData[0]),
};
return response
Is this what you're after?
const input = [
{
"id": "p1", "top": 130, "left" :298, "Key": "test1",
// I've changed this from "special" to "p2"
"Next": "p2"
// rest of input is the same...
},{"id":"p2","Key":"special","specialkey":[{"key":"1","value":"p3"},{"key":"0","value":"p4"},{"key":"2","value":"p5"}],"Next":"","RepeatText": "p8","RepeatTextNew":"p9"},{"id":"p3","user":"aa","Key":"test3","Text":"hi"},{"id":"p4","Key":"special","specialkey":[{"key":"1","value":"p6"},{"key":"0","value":"p7"}]},{"id":"p5","user":"aa","Key":"test5","Text":"hi"},{"id":"p6","user":"aa","Key":"test6","Text":"hi"},{"id":"p7","user":"aa","Key":"test7","Text":"hi"},{"id":"p8","user":"aa","Key":"test8","Text":"hi"},{"id":"p9","user":"aa","Key":"test9","Text": "hi"}];
// Gets an object by its id
const getById = id => input.find(x => x.id === id);
const processObject = ({ Next, specialkey, RepeatText, RepeatTextNew, ...rest }) => {
let processedNext;
if (Next) {
const nextObject = getById(Next);
processedNext = { [nextObject.Key]: processObject(nextObject) };
}
return {
...rest,
// This spread syntax means we don't add the Next or
// specialkey property if it isn't present in the input
// object
...processedNext ? { Next: processedNext } : {},
...RepeatText
? { RepeatText: { [RepeatText]: processObject(getById(RepeatText)) } }
: {},
...RepeatTextNew
? { RepeatTextNew: { [RepeatTextNew]: processObject(getById(RepeatTextNew)) } }
: {},
...specialkey
? {
specialkey: specialkey.map(({ key, value }) => ({
key,
value: processObject(getById(value))
}))
}
: {}
};
}
console.log(processObject(input[0]));
In your code, you seem to be looking up objects by their id, so that's why I changed the first object input's Next from "special" (the Key of the p2 object) to "p2".
Input:
[{
"dimensions": [{
"name": "Size",
"value": "Size1"
},
{
"name": "Color",
"value": "Color1"
},
{
"name": "Pattern",
"value": "1"
}
],
"link": "link",
"title": "title"
},
{
"dimensions": [{
"name": "Size",
"value": "Size2"
},
{
"name": "Color",
"value": "Color1"
},
{
"name": "Pattern",
"value": "2"
}
],
"link": "link1",
"title": "title"
},
{
"dimensions": [{
"name": "Size",
"value": "Size1"
},
{
"name": "Color",
"value": "Color2"
},
{
"name": "Pattern",
"value": "1"
}
],
"link": "link",
"title": "title"
},
{
"dimensions": [{
"name": "Size",
"value": "Size2"
},
{
"name": "Color",
"value": "Color1"
},
{
"name": "Pattern",
"value": "3"
}
],
"link": "link",
"title": "title"
}]
Expected Output:
{
"levels":3,
"level_1_name":"Size",
"level_2_name":"Color",
"level_3_name":"Pattern",
"data":[
{
"value":"Size1",
"data":[
{
"value":"Color1",
"data":[
{
"value":"1"
}
]
}, {
"value":"Color2",
"data":[
{
"value":"4"
}
]
}
]
}, {
"value":"Size2",
"data":[
{
"value":"Color1",
"data":[
{
"value":"3"
}
]
},
{
"value":"Color2",
"data":[
{
"value":"2"
}
]
}
]
}
]
}
I've tried something like that
for(index=0; index<data[0].dimensions.length - 1; index++) {
let temp = _(data).groupBy(function(o) {
return o.dimensions[index].value
})
let keys = Object.keys(temp)
addData(final, keys, temp)
}
obj["data"] = final
function addData(data, keys, temp) {
if (data && data.length) {
return data.forEach(function(data1){
console.log(data1)
return addData(data1, keys, temp)
})
} else {
let data_arr = []
if (Array.isArray(data)) {
keys.forEach(function(key) {
data.push({
value: key,
data: temp[key]
})
})
} else {
keys.forEach(function(key) {
let data_obj = {}
data_obj['value'] = key
data_obj['data'] = temp[key]
data_arr.push(data_obj)
})
data["data"] = data_arr
}
}
}
I've tried the logic to format as per the expected output. It works with level 2 input set, But the logic written doesn't work for level 3 input data set.
Also It would be helpful if you can suggest any algorithms to sort this problem out.
Thanks in advance!
Here is a fairly compact solution using reduce(). (I've edited the input to match your expected output.)
const source = [{
"dimensions": [{
"name": "Size",
"value": "Size1"
},
{
"name": "Color",
"value": "Color1"
},
{
"name": "Pattern",
"value": "1"
}
],
"link": "link",
"title": "title"
},
{
"dimensions": [{
"name": "Size",
"value": "Size2"
},
{
"name": "Color",
"value": "Color2"
},
{
"name": "Pattern",
"value": "2"
}
],
"link": "link1",
"title": "title"
},
{
"dimensions": [{
"name": "Size",
"value": "Size1"
},
{
"name": "Color",
"value": "Color2"
},
{
"name": "Pattern",
"value": "4"
}
],
"link": "link",
"title": "title"
},
{
"dimensions": [{
"name": "Size",
"value": "Size2"
},
{
"name": "Color",
"value": "Color1"
},
{
"name": "Pattern",
"value": "3"
}
],
"link": "link",
"title": "title"
}];
const output = source.reduce((acc, {dimensions: dims}) => {
const levels = dims.length;
// initialize top-level keys based on first object
if (!acc.hasOwnProperty('levels')) {
acc.levels = levels;
dims.forEach((level, i) => acc[`level_${i+1}_name`] = level.name);
acc.data = [];
}
// iterate over dimension objects and merge with accumulator
let parent = acc.data;
dims.forEach((o, i) => {
let lvlObj = parent.find(e => e.value === o.value);
if (!lvlObj) {
lvlObj = i < levels - 1 ?
{value: o.value, data: []} :
{value: o.value};
parent.push({...lvlObj});
}
parent = lvlObj.data;
});
return acc;
}, {});
console.log(output);
This is my json object:
{
"id": 2,
"service": "mobile",
"min": "20",
"per": "10",
"tax": "1",
"categoryservices": [
{
"category": {
"id": 1,
"name": "laptop"
}
},
{
"category": {
"id": 2,
"name": "software"
}
}
]
}
I want my output like this:
{
"id": 2,
"service": "mobile",
"min": "20",
"per": "10",
"tax": "1",
"cats": [1,2] // this 1 and 2 is coming from categoriesservices array inside the category object i have id
}
How to do this using map function? I am new to javascript, which is good approach map or forloop?
See destructuring assignment, Array.prototype.map(), and JSON for more info.
// Input.
const input = {
"id": 2,
"service": "mobile",
"min": "20",
"per": "10",
"tax": "1",
"categoryservices": [
{
"category": {
"id": 1,
"name": "laptop"
}
},
{
"category": {
"id": 2,
"name": "software"
}
}
]
}
// Categories => Objects to Cats => Ids.
const output = (input) => JSON.parse(JSON.stringify({
...input,
cats: input.categoryservices.map(({category: {id}}) => id),
categoryservices: undefined
}))
// Log.
console.log(output(input))
If you are not worried about original object immutability, then try this
obj['cats'] = obj['categoryservices'].map(cat => cat.category.id);
delete obj['categoryservices'];
console.log(obj);
I just use .map() on categoryservices array:
var output = {
"id": 2,
"service": "mobile",
"min": "20",
"per": "10",
"tax": "1",
"categoryservices": [
{
"category": {
"id": 1,
"name": "laptop"
}
},
{
"category": {
"id": 2,
"name": "software"
}
}
]
};
output.cats = output.categoryservices.map((element) =>
element.category.id);
delete output.categoryservices;
console.log(JSON.stringify(output));
use .map() , it return value as array ! You want to change is categoryservices key only ! So delete that after you get wanted value ..
var output = {
"id": 2,
"service": "mobile",
"min": "20",
"per": "10",
"tax": "1",
"categoryservices": [
{
"category": {
"id": 1,
"name": "laptop"
}
},
{
"category": {
"id": 2,
"name": "software"
}
}
]
};
output.cats = output.categoryservices.map(i => i.category.id );
delete output.categoryservices;
console.log(output);
Try this working demo :
var jsonObj = {
"id": 2,
"service": "mobile",
"min": "20",
"per": "10",
"tax": "1",
"categoryservices": [
{
"category": {
"id": 1,
"name": "laptop"
}
},
{
"category": {
"id": 2,
"name": "software"
}
}
]
};
var arr = jsonObj.categoryservices.map(item => item.category.id)
jsonObj.cats = arr;
delete jsonObj.categoryservices;
console.log(jsonObj);
Try this
var testData={
"id": 2,
"service": "mobile",
"min": "20",
"per": "10",
"tax": "1",
"categoryservices": [
{
"category": {
"id": 1,
"name": "laptop"
}
},
{
"category": {
"id": 2,
"name": "software"
}
}
]
}
testData.cats=[];
testData.categoryservices.forEach(function (item) {
testData.cats.push(item.category.id);
});
delete testData.categoryservices;
console.log(testData);
You can try using jquery each:
<div id="log"></div>
var conversation = {
'John': {
1: 'Test message 1',
2: 'Test message 2',
'Reply': {
3: 'Test message 3',
4: 'Test message 4'
}
},
'Jack': {
5: 'Test message 5',
6: 'Test message 6'
}
};
function iterate(obj) {
if (typeof obj === 'string') {
$('#log').append((obj + '<br/>'));
}
if (typeof obj === 'object') {
$.each(obj, function(key, value) {
iterate(value);
});
}
}
iterate(conversation);
I am getting a result in my JavaScript file which I want to convert into another object.
My original result
[
{
"SName": "Set1",
"Elements": [
{
"Id": "3",
"Name": "Name1"
},
{
"Id": "5",
"Name": "Name2"
}
]
},
{
"SName": "Set2",
"Elements": [
{
"Id": "7",
"Name": "Name3"
},
{
"Id": "8",
"Name": "Name4"
}
]
}
]
Convert this to look like array of objects using jQuery or JavaScript. How can I achieve this?
[
{
"SName": "Set1",
"Id": 3,
"Name": "Name1"
},
{
"SName": "Set1",
"Id": 5,
"Name": "Name2"
},
{
"SName": "Set2",
"Id": 7,
"Name": "Name3"
},
{
"SName": "Set2",
"Id": 8,
"Name": "Name4"
}
]
var data = [
{
"SName": "Set1",
"Elements": [
{
"Id": "3",
"Name": "Name1"
},
{
"Id": "5",
"Name": "Name2"
}
]
},
{
"SName": "Set2",
"Elements": [
{
"Id": "7",
"Name": "Name3"
},
{
"Id": "8",
"Name": "Name4"
}
]
}
];
console.log(data);
var newData = data.reduce(function (newArray, currentSet) {
return newArray.concat(currentSet.Elements.map(function (element) {
return Object.assign( { SName: currentSet.SName }, element);
}));
}, []);
console.log(newData);
The key here is the reduce function. What we are doing is creating a brand new array, by looping through each value of the outer array. We continuously concatenate onto our new array with the values we map from the inner array.
You could iterate the array, the Elements and the properties and build a new object and push it to the result set.
var array = [{ "SName": "Set1", "Elements": [{ "Id": "3", "Name": "Name1" }, { "Id": "5", "Name": "Name2" }] }, { "SName": "Set2", "Elements": [{ "Id": "7", "Name": "Name3" }, { "Id": "8", "Name": "Name4" }] }],
result = [];
array.forEach(function (a) {
a.Elements.forEach(function (b) {
var o = { SName: a.SName };
Object.keys(b).forEach(function (k) {
o[k] = b[k];
});
result.push(o);
});
});
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
ES6
var array = [{ "SName": "Set1", "Elements": [{ "Id": "3", "Name": "Name1" }, { "Id": "5", "Name": "Name2" }] }, { "SName": "Set2", "Elements": [{ "Id": "7", "Name": "Name3" }, { "Id": "8", "Name": "Name4" }] }],
result = [];
array.forEach(a => a.Elements.forEach(b => result.push(Object.assign({ SName: a.SName }, b))));
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
You can do this with reduce(), forEach() and Object.assign()
var data = [{
"SName": "Set1",
"Elements": [{
"Id": "3",
"Name": "Name1"
}, {
"Id": "5",
"Name": "Name2"
}]
}, {
"SName": "Set2",
"Elements": [{
"Id": "7",
"Name": "Name3"
}, {
"Id": "8",
"Name": "Name4"
}]
}]
var result = data.reduce(function(r, e) {
e.Elements.forEach(function(o) {
r.push(Object.assign({SName: e.SName}, o))
})
return r;
}, [])
console.log(result)
Here is solution using jQuery, here is jsfiddle:
https://jsfiddle.net/noitse/3uk9qjnf/
I hope you know all key names so it wont be problem to do it fixed.
var json = [
{
"SName": "Set1",
"Elements": [
{
"Id": "3",
"Name": "Name1"
},
{
"Id": "5",
"Name": "Name2"
}
]
},
{
"SName": "Set2",
"Elements": [
{
"Id": "7",
"Name": "Name3"
},
{
"Id": "8",
"Name": "Name4"
}
]
}
]
var newJSON = []
$(json).each(function(index,value){
$(value.Elements).each(function(index1,value1){
newJSON.push({"SName":value.SName,"Id":value1.Id,"Name":value1.Name})
})
})
alert(JSON.stringify(newJSON))
Here is code , what it does it loops through first JSON , then loops through its elements , then it push it to new array
You could use the $.extend method, which lets you create a copy of an object, while merging with another object.
var source = [] // Replace with the initalization of your source array
var destination = [];
for (var i = 0; i < source.length; i++) {
var node = source[i];
for (var j = 0; j < node.Elements.length; j++) {
var subNode = node.Elements[j];
newNode = $.extend(subNode, node);
delete newNode["Elements"];
destination.push(newNode);
}
}
You can run the code in this fiddle.