re building a json from an exciting one nodejs - javascript

I've the current JSON that looks like this
{
"_id": "5371f7171b27d11418bd9b46",
"name": "a",
"length": 14
},
{
"_id": "5371f7171b27d1143bd9b46",
"name": "ab",
"length": 3
}
and I'm trying to get it to look like this one,
5371f7171b27d11418bd9b46: {
name: "a",
length: 14,
toc: [] // in the future it will be in the json I get.
},
5371f7171b27d1143bd9b46: {
name: "ab",
length: 3,
toc: []
}
this is what I tried,
var arrenged = {};
_.forEach(result, function(item) {
arrenged[item._id] = arrenged[item._id] || {};
arrenged[item._id][item.name] = arrenged[item._id][item.name] || {};
arrenged[item._id][item.name].push(item);
arrenged[item._id]['direction'] = 'rtl';
arrenged[item._id]['toc'] = "[]";
});
res.jsonp(arrenged);
but I get TypeError: Object # has no method 'push', not sure what I'm doing wrong.
thanks!

Could just do:
var newObject = {};
for (var i = 0; i < data.length; i++) { //data is your current array of objects
var id = data[i]._id;
newObject[id] = {};
newObject[id].name = data[i].name;
newObject[id].length = data[i].length;
newObject[id].toc = [];
}
Fiddle: http://jsfiddle.net/KWjb3/

Related

Get parent object after looping through nested array

I have a nested array I loop through every element in the array and read the value of key title then I check if the value includes a certain string if it includes the search string that value will be pushed to another array then I sort the new array by occurrence of the search string so that the index position of every element in the new array depends how similar the array element string is with the search string and also the array elements will be sorted by ascending letter order. Now this whole procedure works fine. What I want is once I get the sorted new array I want to loop though it then get the object containing the new arrays element as a title. How can I achieve this. Read the comments in my code to better understand my question. Thanks in advance.
note: When retrieving the object it should keep the index position of the newly created array.
const allArr = [
[{
"id": "1",
"title": "blaha"
}, {
"id": "2",
"title": "blahe"
}, {
"id": "3",
"title": "dhs"
}],
[{
"id": "4",
"title": "blahc"
}, {
"id": "5",
"title": "shg"
}]
]
const searchTerm = 'blah'
let existsArr = []
let tempArr = []
for (var i = 0; i < allArr.length; i++) {
const allAds = allArr[i]
for (var j = 0; j < allAds.length; j++) {
if (allAds[j].title.toLowerCase().includes(searchTerm.toLowerCase())) {
existsArr.push(allAds[j].title)
}
}
}
tempArr = existsArr.filter(a => a.toLowerCase().includes(searchTerm))
const startsWith = (string, value) => string.substring(0, value.length).toLowerCase() === value
const sortByOccurance = JSON.stringify(tempArr.sort((a, b) => {
const aStartsWith = startsWith(a, searchTerm)
const bStartsWith = startsWith(b, searchTerm)
if (aStartsWith && !bStartsWith) {
return -1
} else if (!aStartsWith && bStartsWith) {
return 1;
}
return b > a ? -1 : 1
}))
console.log(sortByOccurance)
//now I want to get the object of every title found in sortByOccurance from allArr
//expected output:
//[{"id": "1", "title": "blaha"}, {"id": "4", "title": "blahc"}, {"id": "2", "title": "blahe"}]
Array.flat flattens the array a level (or more). That makes it easier to find an item.title === term. So now we can loop over array and build our result array.
Update: not using Array.flat to allow for duplicate names with different id. Instead, we search for the first match (a "deep" search) and then delete it so next time will find next item.
const allArr = [
[{
"id": "1",
"title": "blaha"
}, {
"id": "2",
"title": "blahe"
}, {
"id": "3",
"title": "dhs"
}],
[{
"id": "4",
"title": "blahc"
}, {
"id": "5",
"title": "shg"
}],
[{
"id": "6",
"title": "blaha"
}]
]
const searchTerm = 'blah'
let existsArr = []
let tempArr = []
for (var i = 0; i < allArr.length; i++) {
const allAds = allArr[i]
for (var j = 0; j < allAds.length; j++) {
if (allAds[j].title.toLowerCase().includes(searchTerm.toLowerCase())) {
existsArr.push(allAds[j].title)
}
}
}
tempArr = existsArr.filter(a => a.toLowerCase().includes(searchTerm))
const startsWith = (string, value) => string.substring(0, value.length).toLowerCase() === value
const sortByOccurance = JSON.stringify(tempArr.sort((a, b) => {
const aStartsWith = startsWith(a, searchTerm)
const bStartsWith = startsWith(b, searchTerm)
if (aStartsWith && !bStartsWith) {
return -1
} else if (!aStartsWith && bStartsWith) {
return 1;
}
return b > a ? -1 : 1
}))
function find_deep(arr, term) {
for (var i = 0; i < arr.length; i++) {
var value = arr[i]
if (Array.isArray(value)) {
var res = find_deep(value, term)
if (res) {
return res;
}
}
if (value.title === term) {
return value;
}
}
return null;
}
console.log(sortByOccurance)
var result = [];
JSON.parse(sortByOccurance).forEach(function(term) {
var found = find_deep(allArr, term)
if (found) {
result.push({ ...found
})
delete found.title; // <--- changes original allArr.
}
})
console.log(result)
.as-console-wrapper {
max-height: 100% !important
}

Push items in an array in Javascript?

I'm working on school-app. person enter students marks from frontend and I've to store it in my backend. I know my data-structure is quite bad. but this is only way I can comfortly use and fit it in my front end application/website.
codeSandbox link
Full Code:
//This data is already set need to push information in this array.
let student = [{
"detail": {
"name": "Mark",
"surname":"widen"
},
}];
//formatting the query in json.
const keys = Object.keys(query)[0].split(",")
const values = Object.values(query)[0].split(",")
const newObj = {}
for (let i = 0; i < keys.length; i++) {
newObj[keys[i]] = values[i]
}
// I've to push it along with "academic-year". so,
for (let a = 0; a < newObj.length; a++) {
const year = a + "st-Year"
console.log(year) // Expected Output: 1st-Year and 2nd-Year
}
// How to run this both for-loop synchronously way ?? AND
//pushing with "ObtainedMarks" and "year" (Error over here)
student.push({
ObtainedMarks: {
year : [
{ physics: newObj }
],
year : [
{ physics: newObj }
]
}
})
console.log(student) //Here's I want expected Output
Expected Output:
let student = [{
"detail": {
"name": "Mark",
"surname":"widen"
},
ObtainedMarks: {
"1st-Year": [
{ physics: { "marks": "500" } } //Physics subject is default.
],
"2nd-Year": [
{ physics: { "mark": "200" } } //Physics subject is default.
]
}
}];
I want to push returned data in student array. with 1st-Year
and 2nd-Year's for-loop.
You can do the conversion in your for-loop
let student = [{
"detail": {
"name": "Mark",
"surname": "widen"
},
}];
let query = {
"marks,mark": "500,200"
}
const keys = Object.keys(query)[0].split(",");
const values = Object.values(query)[0].split(",");
const marks = {}
for (let i = 0; i < keys.length; i++) {
marks[i === 0 ? `${i+1}st-year` : `${i+1}nd-year`] = [{
physics: {
[keys[i]]: values[i]
}
}];
}
student.push({
obtainedMarks: marks
});
console.log(student);
Alternative way: map through the keys and create an object from entries after manipulating the data.
let student = [{
"detail": {
"name": "Mark",
"surname": "widen"
},
}];
let query = {
"marks,mark": "500,200"
}
const keys = Object.keys(query)[0].split(",");
const values = Object.values(query)[0].split(",");
const marks = Object.fromEntries(keys.map((k, i) => {
return [
i === 0 ? `${i+1}st-year`: `${i+1}nd-year`,
[{ physics: { [k]: values[i] }}]
];
}));
student.push({
obtainedMarks: marks
});
console.log(student);

create an array of objects from an object and array

I have an object:
items = {
0: "foo",
1: "bar",
2: "baz"
};
and an array:
category = [
"type1",
"type2",
"type3"
];
I want to merge these with the desired output:
newArray = [
{type1:"foo"},
{type2:"bar"},
{type3:"baz"}
];
I thought I would be able to do it quite simply with a for loop like the following (though any method would do):
var obj = {};
for (var i = 0; i < category.length; i++) {
obj [category[i]] = items[i];
newArray.push(obj);
}
What I actually get is :
[{"type1":"foo","type2":"bar","type3":"baz"},
{"type1":"foo","type2":"bar","type3":"baz"},
{"type1":"foo","type2":"bar","type3":"baz"}]
I guess it's iterating through all instances of i for each obj each time but how do I amend to get the desired output?
https://jsfiddle.net/ormxq0y4/3/
you want a new object for each iteration
for (var i = 0; i < category.length; i++) {
var obj = {};
obj [category[i]] = items[i];
newArray.push(obj);
}
I guess this should do it;
var items = {
0: "foo",
1: "bar",
2: "baz"
},
category = [
"type1",
"type2",
"type3"
],
newArray = category.map((e,i) => ({[e]:items[i]}));
console.log(newArray)
You could try something like this ->
category.forEach(function (e,i) {
var obj = {};
obj[e] = items[i];
newArray.push(obj);
});
var items = {
0: "foo",
1: "bar",
2: "baz"
},
category = [
"type1",
"type2",
"type3"
];
var reformattedArray = category.map(function(obj, index){
var rObj = {};
rObj[obj] = items[index];
return rObj;
});
console.log("reformattedArray", reformattedArray);
https://jsfiddle.net/s6ntL2eo/
Here is how i would do it. But in my honest opinion is a bit risky if you relay only on the items KEY to be the connection point for the array. Please also keep in mind that an object allows the key to be eigther string or number (that's why items[+key]).
var items = {
0: "foo",
1: "bar",
2: "baz"
};
var categories = [
"type1",
"type2",
"type3"
];
var newArray = [];
categories.forEach(function (category, key) {
if (items[+key]) {
var tmpO = {};
tmpO[category] = items[+key];
newArray.push(tmpO);
}
});
console.log(newArray)
You are not making a separate object each time. Instead you are pushing the same object three times, and adding type1, type2, type3 properties to this one object.
Simply moving var obj = {} into the loop fixes your issue.
newArray = [];
items = {
0: "foo",
1: "bar",
2: "baz"
};
category = [
"type1",
"type2",
"type3"
];
for (var i = 0; i < category.length; i++) {
var obj = {};
obj[category[i]] = items[i];
newArray.push(obj);
}
var title = document.getElementById("title");
title.innerHTML = JSON.stringify(newArray);
With the result: [{"type1":"foo"},{"type2":"bar"},{"type3":"baz"}]

JSON - array of objects into objects of arrays

I have a series of JSON entries:
[{"num": "1","name_A": "Alex" ,"name_B": "Bob"}, {"num": "2","name_A": "Anne" ,"name_B": "Barbra"}]
I am trying to convert this array of Objects as painlessly as possible into two objects - one with title name_A, and the second with the title name_B. Objects have to contain the title and an array of matching num-name pairs:
[{title: "name_A", names:[{"1", "Alex}, {"2", "Anne"}]}, {title:"name_B", names: [{"1", "Bob"}, {"2", "Barbra"}]}]
At first I tried simply to create two objects by reducing the array of object twice, once for name_A and second time for name_B and later glue everything together:
// get 'names' array
var name_A = objArray.reduce(function(memo, curr) {
memo.push({curr.num, curr.name_A})
return memo;
}, []);
But even this is failing. Why there is no push method for memo if I initialize reduce with an empty array?
And second question, am I on a right track or is there a better way to achieve this?
Comments inline, made a few minor corrections to the expectations.
var input = [{ "num": "1", "name_A": "Alex", "name_B": "Bob" }, { "num": "2", "name_A": "Anne", "name_B": "Barbra" }]
var output = input.reduce(function (a, b) {
// construct new objects and set their properties
var i = {};
i[b.num] = b.name_A;
var j = {};
j[b.num] = b.name_B;
// add them to our collection elements
a[0].names.push(i);
a[1].names.push(j);
return a;
// initializing our collection
}, [{ title: "name_A", names: [] }, { title: "name_B", names: [] }]);
// pretty print our output
console.log(JSON.stringify(output, null, " "))
var input = [{ "num": "1", "name_A": "Alex", "name_B": "Bob" }, { "num": "2", "name_A": "Anne", "name_B": "Barbra" }]
var output = input.reduce(function (a, b) {
// construct new objects and set their properties
var i = {};
i[b.num] = b.name_A;
var j = {};
j[b.num] = b.name_B;
// add them to our collection elements
a[0].names.push(i);
a[1].names.push(j);
return a;
// initializing our collection
}, [{ title: "name_A", names: [] }, { title: "name_B", names: [] }]);
so.log(output)
<pre id="output"></pre>
<script>
var so = {
log: function(o) {
document.getElementById("output").innerHTML = JSON.stringify(o, null, " ")
}
}
</script>
The problem with your code is that { curr.num, curr.name_A } is not a valid object, it's missing the property names. I've added properties num and name in my code below.
var name_A = [];
var name_B = [];
objArray.forEach(function(curr) {
name_A.push({num: curr.num, name: curr.name_a});
name_B.push({num: curr.num, name: curr.name_B});
});
var result = [
{ title: "name_A" }, names: name_A },
( title: "name_B" }, names: name_B }
];
Also, if you want to make an array out of the results of looping over an array, you should use .map rather than .reduce.
Assuming only property num is fixed. All other properties are treated as data, like name_A or name_B.
var a = [{ "num": "1", "name_A": "Alex", "name_B": "Bob" }, { "num": "2", "name_A": "Anne", "name_B": "Barbra" }],
result = [];
a.forEach(function (el) {
var num = el.num;
Object.keys(el).forEach(function (k) {
function tryFindIndexAndSetNames(aa, i) {
if (aa.title === k) {
result[i].names[num] = el[k];
return true;
}
}
if (k !== 'num' && !result.some(tryFindIndexAndSetNames)) {
var o = {};
o[num] = el[k];
result.push({ title: k, names: o });
}
});
});
document.write('<pre>' + JSON.stringify(result, 0, 4) + '</pre>');

Javascript array format for charts

I have two arrays
A =[1990,1991,....]
B=[a,b,c,d,e,f,...]
I want the resultant array in this format
Resultant=[{
name: 1990,
data: [a,b,c]
},{
name: 1991,
data: [d,e,f]
},...
]
Please help me how will I make it using for loops?
How about this:
var b= ["a","b","c","d","e","f"];
var result = [1990,1991].map(function(n){ return { name:n, data: b.splice(0,3)} });
This will format data with Array.prototype.map, based on your (rather vague) requirement:
var A = [1990,1991];
var B = ["a","b","c","d","e","f"];
var formatted = A.map(function (name, i) {
return {
name: name,
data: B.slice(i*3, i*3+3)
}
});
/*[
{
"name": 1990,
"data": [
"a",
"b",
"c"
]
},
{
"name": 1991,
"data": [
"d",
"e",
"f"
]
}
]*/
Assuming that for each in A, you want data to store 3 elements of B. I've stuck with your requirement of using for loops.
var Resultant = [];
for (var i = 0; i < a.length; i++) {
var data = [];
for (var j = 0; j < 3, B.length > 0; j++) {
data.push(B.shift());
}
Resultant.push({name: A[i], 'data': data});
}
This worked for me:
http://jsfiddle.net/s5zdD/ <-- see jsfiddle to show
A =[1990,1991,1992];
B=['a','b','c','d','e','f','g','h','i'];
var Resultant = jQuery.map(A, function(i,v){
// if no jQuery use:
// var Resultant = A.map(function(i,v){
return {
'name':A[v],
'data': B.splice(0,3)
}
})
console.log(Resultant);

Categories

Resources