1

I have a JSON array like below:

rows =[
        {
            "ID":132,
            "TITLE":"Questions one",
            "DESCRIPTION":"Questions one DESCRIPTION",
            "EXPERT_RATING":3,
            "DURATION":15,
            "SOURCE_URL":"http://testing.com",
            "COMMENT":null,
            "UserID": 1214
        },
        {
            "ID":137,
            "TITLE":"Questions two",
            "DESCRIPTION":"Questions two description",
            "EXPERT_RATING":3,
            "DURATION":15,
            "SOURCE_URL":"http://question2.com",
            "COMMENT":null,
            "UserID": 1214
        }
    ]

Now, I want to push it into an array, so it should look like below:

res[132] = ['Questions one', 'Questions one DESCRIPTION', 3, 15, 'http://testing.com', null, 1214]
res[137] = ['Questions two', 'Questions two DESCRIPTION', 3, 15, 'http://question2.co', null,1214]

I have tried the following cod, but is showing lot of null records

rows.forEach(function(key){

                recJson[key.ID] = [key.TITLE, key.DESCRIPTION, key.EXPERT_RATING, key.DURATION, key.SOURCE_URL, key.COACHING_TIPS, key.MGR_COMMENT, key.UserID]             
            });

console.log(recJson);

Tell me what I am doing wrong?

Sricharan
  • 395
  • 1
  • 16

5 Answers5

2

If you're using that code directly, you have an inconsistency or typo. Your dataset seems to be interchanging between TITLE and RTITLE. If your data is truly like that, you can indiscriminately push all the values of each entry to an array using a reduce function and Object.values:

rows.reduce((acc, curr) => {
  acc[curr["ID"]] = Object.values(curr);
  return acc;
}, {})

Which will result in this:

{
  132: [132, "Questions one", "Questions one DESCRIPTION", 3, 15, "http://testing.com", null]
  137: (7) [137, "Questions two", "Questions two description", 3, 15, "http://question2.com", null]
}

This should give you what you'd like.

LMulvey
  • 1,326
  • 4
  • 14
1

Here my approach.

var rows = [{
  "ID": 132,
  "TITLE": "Questions one",
  "DESCRIPTION": "Questions one DESCRIPTION",
  "EXPERT_RATING": 3,
  "DURATION": 15,
  "SOURCE_URL": "http://testing.com",
  "COMMENT": null
 },
 {
  "ID": 137,
  "RTITLE": "Questions two",
  "DESCRIPTION": "Questions two description",
  "EXPERT_RATING": 3,
  "DURATION": 15,
  "SOURCE_URL": "http://question2.com",
  "COMMENT": null
 },
 {
  "ID": 137,
  "RTITLE": "Questions three",
  "DESCRIPTION": "Questions three description",
  "EXPERT_RATING": 3,
  "DURATION": 15,
  "SOURCE_URL": "http://question3.com",
  "COMMENT": null
 },
 {
  "ID": 137,
  "RTITLE": "Questions four",
  "DESCRIPTION": "Questions four description",
  "EXPERT_RATING": 3,
  "DURATION": 15,
  "SOURCE_URL": "http://question4.com",
  "COMMENT": null
 }
];
var arr = rows.map(ar => Object.values(ar));
var obj = {};
arr.map(ar => {
 var id = ar[0];
 ar.splice(0, 1);
 //if duplicate key occures creating a nested array.
 if (obj.hasOwnProperty(id)) {
  if (Array.isArray(obj[id][0])) {
   obj[id].push(ar);
  } else {
   obj[id] = [obj[id], ar];
  }
 } else {
  obj[id] = ar;
 }
});

console.log(obj);

Edited

Updated for duplicate key occurrence.

Prabu samvel
  • 1,316
  • 6
  • 15
  • Actually, In my result set I have total 73 records, when I am using your solution using Object.values, it is removing some and it is outputting only 33 records. Why is it hapening? Is there a way where I can get all the 73 records in the above format with key and values? – Sricharan Apr 24 '19 at 11:13
  • is that all the 73 records are in the same structure? I mean, Is there any nested objects or array inside that? @sony – Prabu samvel Apr 24 '19 at 11:16
  • All the records are in the same structure, but there will be duplicate keys with different values, those keys should not be eliminated while outputting – Sricharan Apr 24 '19 at 11:26
  • For duplicate keys do you want nested array? @sony – Prabu samvel Apr 24 '19 at 12:00
  • like this. `{"137": [[ "Questions two", "Questions two description", 3, 15, "http://question2.com", null ],[ "Questions three", "Questions three description", 3, 15, "http://question3.com", null ]]}` – Prabu samvel Apr 24 '19 at 12:01
  • You are welcome. You can support me by upvoting my correct answers. :) @sony – Prabu samvel Apr 24 '19 at 12:58
0

The bit missing from your code, is:

var recJson = [];

which means you're adding an entry to a javascript array by index, so, in order for javascript to add index 132, it has to add indices 0-131 first - so you get a lot of null/undefineds.

You could instead push each entry to the array, but this would not let you access them by ID - so better to use an object

var recJson = {};

which will add your values as properties.

rows = [{
    "ID": 132,
    "TITLE": "Questions one",
    "DESCRIPTION": "Questions one DESCRIPTION",
    "EXPERT_RATING": 3,
    "DURATION": 15,
    "SOURCE_URL": "http://testing.com",
    "COMMENT": null
  },
  {
    "ID": 137,
    "RTITLE": "Questions two",
    "DESCRIPTION": "Questions two description",
    "EXPERT_RATING": 3,
    "DURATION": 15,
    "SOURCE_URL": "http://question2.com",
    "COMMENT": null
  }
]


var recJson = {};
rows.forEach(function(key) {
  recJson[key.ID] = [key.RTITLE, key.DESCRIPTION, key.EXPERT_RATING, key.DURATION, key.SOURCE_URL, key.COACHING_TIPS, key.MGR_COMMENT, key.ATTUID];
});

console.log(recJson);
freedomn-m
  • 21,261
  • 4
  • 28
  • 53
  • This is not a good idea because for getting any element with specific idea you will need to iterate through whose array. – Maheer Ali Apr 23 '19 at 16:26
  • @MaheerAli I was just updating for that :) It's a viable option that depends on how OP want's to access the values. As OP is adding by key, it's a safe assumption they want to access by key. – freedomn-m Apr 23 '19 at 16:29
  • @freedomn-m, I want the output to be mapped with key's as like my above given result... { 132: [132, "Questions one", "Questions one DESCRIPTION", 3, 15, "http://testing.com", null] 137: (7) [137, "Questions two", "Questions two description", 3, 15, "http://question2.com", null] } – Sricharan Apr 24 '19 at 08:19
0
  • First, you need to make sure your array is appropriately sized for those indices.
  • Next, you need some way to get the order of the fields. (Make sure your field name are consistent)
  • Last, just reduce the fields for each row to grab the appropriate value.

let rows = [{
  "ID": 132,
  "TITLE": "Questions one",
  "DESCRIPTION": "Questions one DESCRIPTION",
  "EXPERT_RATING": 3,
  "DURATION": 15,
  "SOURCE_URL": "http://testing.com",
  "COMMENT": null
}, {
  "ID": 137,
  "RTITLE": "Questions two",
  "DESCRIPTION": "Questions two description",
  "EXPERT_RATING": 3,
  "DURATION": 15,
  "SOURCE_URL": "http://question2.com",
  "COMMENT": null
}];

let res = new Array(138);
let fields = [ 'RTITLE', 'DESCRIPTION', 'EXPERT_RATING', 'DURATION', 'SOURCE_URL', 'COMMENT' ];

rows.forEach(row => {
  res[row.ID] = fields.reduce((arr, field) => arr.concat(row[field]), []);
});

console.log(res);
.as-console-wrapper { top: 0; max-height: 100% !important; }

As others have suggested, maybe an object would be better.

rows.reduce((obj, row) => {
  return Object.assign(obj, { [row.ID] : fields.reduce((arr, field) => {
    return arr.concat(row[field]);
  }, []) })
}, res);

let rows = [{
  "ID": 132,
  "TITLE": "Questions one",
  "DESCRIPTION": "Questions one DESCRIPTION",
  "EXPERT_RATING": 3,
  "DURATION": 15,
  "SOURCE_URL": "http://testing.com",
  "COMMENT": null
}, {
  "ID": 137,
  "RTITLE": "Questions two",
  "DESCRIPTION": "Questions two description",
  "EXPERT_RATING": 3,
  "DURATION": 15,
  "SOURCE_URL": "http://question2.com",
  "COMMENT": null
}];

let res = {};
let fields = [ 'RTITLE', 'DESCRIPTION', 'EXPERT_RATING', 'DURATION', 'SOURCE_URL', 'COMMENT' ];

rows.reduce((obj, row) => Object.assign(obj, { [row.ID] : fields.reduce((arr, field) => arr.concat(row[field]), []) }), res);

console.log(res);
.as-console-wrapper { top: 0; max-height: 100% !important; }
Mr. Polywhirl
  • 31,606
  • 11
  • 65
  • 114
0

If you are able to use it, I suggest to use a Map() in this case to hold your new structure. Creating an array with holes is not a good idea. Alternatively you can use an object, where the keys are the ids and the values the desired array.

This will be the Map solution:

const rows = [
  {
    "ID":132,
    "TITLE":"Questions one",
    "DESCRIPTION":"Questions one DESCRIPTION",
    "EXPERT_RATING":3,
    "DURATION":15,
    "SOURCE_URL":"http://testing.com",
    "COMMENT":null
  },
  {
    "ID":137,
    "RTITLE":"Questions two",
    "DESCRIPTION":"Questions two description",
    "EXPERT_RATING":3,
    "DURATION":15,
    "SOURCE_URL":"http://question2.com",
    "COMMENT":null
   }
];

let myMap = rows.reduce((acc, o) =>
{
    acc.set(o.ID, [
        o.hasOwnProperty("TITLE") ? o.TITLE : o.RTITLE,
        o.DESCRIPTION,
        o.EXPERT_RATING,
        o.DURATION,
        o.SOURCE_URL,
        o.COMMENT
    ]);
    return acc;
}, new Map());

console.log("Data for id 132:", myMap.get(132));
console.log("Data for id 137:", myMap.get(137));
.as-console {background-color:black !important; color:lime;}
.as-console-wrapper {max-height:100% !important; top:0;}

Note the only way to ensure the resulting array will be ordered as you want is to enumerate all properties in the order you want. You can't trust on Object.values() to give you all arrays with the same order of keys. Read here about this.

Shidersz
  • 15,614
  • 2
  • 15
  • 40