Optmize flattening of an array of nested json objects in JavaScript [closed] - javascript

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about programming within the scope defined in the help center.
Closed 6 years ago.
Improve this question
Supposed to have an array of objects of objects like
[
{
"key_set1": {
int_val: 3,
arr_val: [
1,
3,
4
]
}
},
{
"key_set2": {
string_val: "foo"
}
}
]
I want to flatten inner objects keys to a new root object to get at the end
{
"key_set1": {
"int_val": 3,
"arr_val": [
1,
3,
4
]
},
"key_set2": {
"string_val": "foo"
}
}
Assumed that
This nested structure can have N levels with N > 10
The structure is a valid json object not a javascript object i.e. it has atomit/non atomic types, not function object types;
The whole input json file can be hundreds of KBytes;
The work must be done in JavaScript V8 / ECMAScript6;
The processing time must be of order of milliseconds
A variant of this mapping, needs to parse the input json object and modify the values (like using map array method).
I want to get the most optimized solution for this using built-in methods like forEach and/or fast iterators for, while etc., for the best/worst cases.

As long as I understand it correctly, you like to replace the array with an object and take the first level key as the new key for the result object.
var array = [{ "key_set1": { int_val: 3, arr_val: [1, 3, 4] } }, { "key_set2": { string_val: "foo" } }],
object = {};
array.forEach(function (a) {
var key = Object.keys(a)[0];
object[key] = a[key];
});
console.log(object);

If you "want to get this optimized at its best" - you shouldn't use Array.map in your case as it returns a new array. You just need to iterate fast through the list array and fill the new flattened object. Consider the following "optimized" solution:
var flattened = {}, len = list.length;
while (len--) {
Object.keys(list[len]).forEach((k) => (flattened[k] = list[len][k]));
}
console.log(JSON.stringify(flattened, 0, 4));
The output:
{
"key_set2": {
"string_val": "foo"
},
"key_set1": {
"int_val": 3,
"arr_val": [
1,
3,
4
]
}
}

Related

Map object to another object javascript [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 2 years ago.
Improve this question
Let's say we get an object like this
let formA = {
"a1": 1, "b1":2, "c1":3,
"a2": 11, "b2":12, "c2":13,
"a3": 21, "b3":22, "c3":23
}
And what we have is
let formB = {
"a1": 0, "b1":0, "c1":0,
"a2": 0, "b2":0, "c2":0
}
And the result must be
let result = [
{"a1": 1, "b1":2, "c1":3, "a2": 11, "b2":12, "c2":13}, // Form B
{"a1": 21, "b1":22, "c1":23, "a2": 0, "b2":0, "c2":0} // Form B
]
Once the given object properties gets filled up, it must create a new object for the remaining mapped like series.
Builds an array that holds the number of formB shaped objects needed to contain all values of formA.
Builds [key,value] pairs by filling in the values using values from formA in groups of values of the number of formB's key/values. Turns it into an Object using fromEntries.
let formA = {
"a1": 1, "b1":2, "c1":3,
"a2": 11, "b2":12, "c2":13,
"a3": 21, "b3":22, "c3":23
}
let formB = {
"a1": 0, "b1":0, "c1":0,
"a2": 0, "b2":0, "c2":0
}
const keys = Object.keys(formB)
const values = Object.values(formA)
console.log(
// build array that is formA.size/formB.size rounded up, map values
Array(Math.ceil(values.length/keys.length)).fill().map((obj,i) =>
// build object using keys from formB, with values from formA
Object.fromEntries(keys.map((key,j)=>[key,values[i*keys.length+j]||0])))
)
Your post isn't clear, but I think you're trying to just merge two objects into one.
This can be done with the es6 spread operator. Here is the MDN docs for the spread operator.
Here is an example I wrote to show how you can use the spread operator to merge two objects and then log the key/values of the merged object:
let object1 = {
firstKey: 'firstValue',
secondKey: 'secondValue'
};
let object2 = {
secondObjectKey: 'secondObjectValue'
}
let mergeObjects = {...object1, ...object2};
for (const [key, value] of Object.entries(mergeObjects)) {
console.log(`${key}: ${value}`);
}
You can also view the example in code sandbox.

How to count the frequencies of elements in an array [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 4 years ago.
Improve this question
Assuming you have an array x = [1, 1, 2, 2, 2, 3], and you had to output a sorted array of objects containing a key-value pair (where the key represents the element, and the value the frequency) like:
y = [
{
2: 3
},
{
1: 2
},
{
3: 1
}
]
The resulting array should be sorted by the values.
What would be the best way of doing this?
You can create a temporary object and do simple .forEach and check if current number exists in object as key, if true plus 1 to the value, otherwise create that key, then with simple .map add all key value pairs in separate object in new array
const x = [1, 1, 2, 2, 2, 3];
const k = {};
x.forEach(v => {
if(k[v]) {
k[v] +=1;
} else {
k[v] = 1;
}
});
const y = Object.keys(k).sort((t,c) => k[c] - k[t]).map(key => ({[key]: k[key]}));
console.log(y);

Adding a new JSON object in front of JSON array set [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about programming within the scope defined in the help center.
Closed 5 years ago.
Improve this question
Playing with nodeJs currently and have been trying to write new data into an existing JSON file, only to have problems with the format as well as getting the right data in. I want to get this new JSON obj to the FIRST of the array list. I did this by grabbing the first index ID, increment it, and tried using unshift() but it isn't adding the way I expected.
JSON file content data.json:
[
{
"id": 3,
"content": "three"
},
{
"id": 2,
"content": "two"
},
{
"id": 1,
"content": "one"
}
]
Code I wrote for new JSON obj I want to add:
var allJSON = fs.readFileSync('data.json');
var allj = JSON.parse(allJSON);
var lastId = parseInt(allj[0].id);
var newData = {
id: ++lastId,
content: "test"
};
var allNewJSON = allj.unshift(JSON.stringify(newData));
// this yields a result of just the number "4" and erased everything else.
Array#unshift does not create and return a new array; instead, it modifies the original array and returns its new length. In your case, this value would be 4. I would suggest ignoring the return value of unshift and simply continuing your code using the allj variable, like so:
var allJSON = fs.readFileSync('data.json');
var allj = JSON.parse(allJSON);
var lastId = parseInt(allj[0].id);
var newData = {
id: ++lastId,
content: "test"
};
allj.unshift(newData);
console.log(allj) // modified as desired!
Edit: As was mentioned in the comments above, you probably don't want to be calling JSON.stringify on the object newData before inserting it into your array. At this point you want to be working with JS objects rather than JSON strings.
Your result is due to the way unshift works.
unshift is a function which returns the length of the updated array.
For example
> const a = [10, 20, 30];
> a.unshift(5);
4
That's right, the call to unshift returns 4, because the updated array has 4 elements.
Let's see the updated value of a:
> a
[5, 10, 20, 30]

Inserting an object so the array stays sorted

I have an enum of different Steps
export enum StepCategory {
START = 0,
POSITION_1 = 1,
TRANSPORT = 2,
RECEIVER = 3,
END = 4,
NO_STEP_MATCH = 5
}
This will later result in an array, where for every Step I have an object. The Problem is I won't load all the information at once, so i can'tdo a simple for-loop and push each item chronogically. I could be that I first load the value for Step 4, so my array would be:
var array = [{"END" , "POSITIVE"}]
Afterwards I would get the Info for Step 2, then I would have:
var array = [{"END", "POSITIVE"}, {"TRANSPORT", "POSITIVE"}]
But this is not sorted.
What should I do? Should I declare an array of 6 undefined values
var array = [undefined, undefined, undefined, undefined, undefined, undefined]
This way I wouldn't need any sorting-algorithm after each Update, and can just push the value at the right position.
Just some small Info: I use AngularJS 1, Typescript and Lodash
In plain Javascript, you could sort it with an object and the assigned values of the key.
var StepCategory = { START: 0, POSITION_1: 1, TRANSPORT: 2, RECEIVER: 3, END: 4, NO_STEP_MATCH: 5 },
array = [["END", "POSITIVE"], ["TRANSPORT", "POSITIVE"]];
array.sort(function (a, b) {
return StepCategory[a[0]] - StepCategory[b[0]];
});
console.log(array)
First of all, this is - as someone mentioned in the comments - not syntactically correct:
var array = [{"END", "POSITIVE"}, {"TRANSPORT", "POSITIVE"}]
I assume that this was just a typo writing this question. Additionally if you actually use the enum in your array as key and just left it out for demonstration purposes, I would expect your array of objects to look something like this:
var array = [{StepCategory.END: "POSITIVE"}, {StepCategory.TRANSPORT: "POSITIVE"}]
In order to sort this with LoDash you could use something like this:
var sortedArray = _.sortBy(array, i => Object.keys(i)[0]);
This sorts your array by the value of the first key of each object which refers to your enum value.

How do I sort an array of objects by a particular field? [duplicate]

This question already has answers here:
Sort array of objects by string property value
(57 answers)
Sorting an array of objects by property values
(35 answers)
Closed 7 years ago.
Sort object by value:
test": [{
"position_order": 3,
}, {
"position_order": 1,
}]
How can I sort this so that obviously the position_order 1 comes first in the array of objects?
Array.Prototype.Sort allows you to specify a comparison function.
test.sort(function(a, b) {
if(a.position_order < b.position_order) {
return -1;
}
if(b.position_order < a.position_order) {
return 1;
}
return 0;
});
You should consider using Underscore, an amazing JS library for manipulating collections, functions and objects. It works both in the client and in the server (Node.js).
That's how you do it with Underscore.
test = [{
"position_order": 3,
}, {
"position_order": 1,
}];
var ordered = _.sortBy(test, 'position_order');
Use the array sort function
var test = [{
"position_order": 3,
}, {
"position_order": 1,
}];
test.sort(function(a,b){
return a.position_order >= b.position_order ? 1 : -1
})

Categories

Resources