javascript recursive function concat not working - javascript

I have a nested array of objects like below and I'm trying to push all the values in to a single array. all the values are located in sp->it->value or sp->it->it->value
[
{
"sp": [
{
"it":[
{"value":5}
]
},
...
],
"b": {
...
}
},
{
"sp": [
{
"it":[
{"nm":5}
]
}
],
"b": {
...
}
},
{
"sp": [
{
"it":[
{
"it":[
{"value":5}
]
}
]
}
],
"b": {
...
}
},
]
and here is what I have tried
const getValues = (js) => {
let values = []
js.map((val,i) => {
if("sp" in val) values.concat(getValues(val.sp))
else if("it" in val) values.concat(getValues(val.it))
else if("value" in val) values.push(val.value)
})
return values
}
I thought I could concatenate the returned value from the recursive call since it returns an array but the above code returns empty array. Any insights?
Edit fixed the typo on sp object. It is array of objects.

Array.prototype.concat()
The concat() method is used to merge two or more arrays. This method does not change the existing arrays, but instead returns a new array.
So those lines do nothing:
if("sp" in val) values.concat(getValues(val.sp))
else if("it" in val) values.concat(getValues(val.it))
You need to write:
if("sp" in val) values = values.concat(getValues(val.sp))
else if("it" in val) values = values.concat(getValues(val.it))
And you should not use map if you don't use it's result. Use forEach instead.

This is because you are passing val.sp to function which is not array but it is an object and .map is a property of an array

Related

JavaScript: format CSV array to Json format

I have the following array which I have extracted from csv file
array
[
{ "Date;Department;Value": "2022-09-08;dept1;7856"},
{ "Date;Department;Value": "2022-09-08;dept2;9876"}
]
I need the following output:
[
{
"Date":"2022-09-08",
"Department":"dept1",
"Value":7856
},
{
"Date":"2022-09-08",
"Department":"dept2",
"Value":9876
}
]
That's quite doable, just take the problem step by step:
const array = [
{ "Date;Department;Value": "2022-09-08;dept1;7856" },
{ "Date;Department;Value": "2022-09-08;dept2;9876" }
];
const result = array
.map(Object.entries) // Convert the objects to more easily accessible arrays.
.map(([[k, v]]) => { // Grab the key / value strings
const keys = k.split(';'); // Split the keys into separate entries.
const values = v.split(';'); // Split the values into separate entries.
// Join the array of keys with the array of values, parsing numbers if possible.
return keys.reduce((obj, key, i) => {
obj[key] = isNaN(values[i]) ? values[i] : Number(values[i]);
return obj;
}, {});
});
console.log(result);

Flatten inner array but assign outer properties

I have an input like this:
var input = [
{
"inner_array": [
{
"inner_data": "inner_data1"
},
{
"inner_data": "inner_data2"
}
],
"outer_data": "outer_data",
}
];
And I'd like to process it so it becomes this.
var output = [
{
"inner_data": "inner_data1",
"outer_data": "outer_data",
},
{
"inner_data": "inner_data2",
"outer_data": "outer_data",
}
];
In words: I'd like to flatten an inner array, while still keeping the outer array's properties. Does this have an easy solution (with built in lambda array functions), or should I write a function myself which handles this?
You could use .flatMap() on your input array to loop over each object, along with an inner .map() to map each inner_array to a new object. The new object can be a combination of the outer_data value along with the inner_data value. The .flatMap() method will then merge all returned objects from the inner .map() calls for each object within input into one resulting array:
const input = [{ "inner_array": [{ "inner_data": "inner_data1" }, { "inner_data": "inner_data2" } ], "outer_data": "outer_data", }];
const res = input.flatMap(obj => obj.inner_array.map(inner => ({
...inner,
outer_data: obj.outer_data
})));
console.log(res);

How to find dynamically a key values inside an object?

each API request I'm making contains different keys values inside a specific object.
How can I dynamically get the Number value of the second key? ("123112042")
"salesRanks": {
"281052": [ keepaTime, salesRank, ... ]
"123112042": [ keepaTime, salesRank, ... ]
}
Target the Object.keys and get the second index.
const data = {
salesRanks: {
"281052": [1, 1],
"123112042": [2, 2]
}
};
console.log(Object.keys(data.salesRanks)[1]);
Although an object's keys are not really meant to be ordered, you could write an object iterator and assign with destructuring like this:
const obj = {
salesRanks: {
281052: ["keepaTime", "salesRank"],
123112042: ["keepaTime", "salesRank"],
[Symbol.iterator]: function () {
return Object.keys(this).values();
}
},
};
const {
salesRanks: [, second],
} = obj;
console.log(second);

Combine JavaScript array with multiple sub-values (Node.js / NVD3)

I'm trying to setup a Node.js API that sends JSON data to the client for use in an NVD3 chart. The chart accepts JSON input in the following format:
[
{
"key”:”KEY NAME“,
"values":[
[
1138683600000,
14.212410956029
],
[
1141102800000,
13.973193618249
]
]
},
{
"key”:”KEY NAME“,
"values":[
[
1138683600000,
7.1590087090398
],
[
1141102800000,
7.1297210970108
]
]
}
]
However, my Node program currently outputs JSON in this format:
[
{
"key”:”SAME KEY NAME”,
"values":[
1510148301000,
34
]
},
{
"key”:”SAME KEY NAME”,
"values":[
1509626301000,
55
]
},
{
"key”:”SAME KEY NAME“,
"values":[
1509539901000,
62
]
},
{
"key”:”DIFFERENT KEY NAME“,
"values":[
1509453501000,
58
]
}
]
I want to combine any "key" indices that are the same as other ones and merge the "values" with one another in the specified format. I searched all over to find a way to do this, but each method I came across didn't account for multiple pairings within the "value" index.
Any suggestions on how I could do this?
Thanks!
You can use Array.prototype.reduce to accumulate the items from your original array into an object keyed uniquely by the item's key-value. Since this leaves you with an Object instead of an array, you can then use Object.values to spit out the array of values like your example output.
let data = [
{"key":"A", "values":[1510148301000, 34]},
{"key":"A", "values":[1509626301000, 55]},
{"key":"A", "values":[1509539901000, 62]},
{"key":"B", "values":[1509453501000, 58]},
{"key":"B", "values":[1509453501001, 57]},
];
let combined = Object.values(data.reduce((accumulator, item) => {
if (!accumulator[item.key])
accumulator[item.key] = {key: item.key, values: []};
accumulator[item.key].values.push(item.values);
return accumulator;
}, {}));
console.log(combined);
I'm not sure about what you want (merge?), but it seems to be like that:
function combine (obj) {
var combined = {}
for (let key in obj) {
if (obj.hasOwnProperty(key)) {
if (!!combined[key]) {
combined[key] = [].concat(combined[key], obj[key].values) // everything in one
// or
// combined[key].push(obj[key].values) // everything in distinct arrays
} else {
combined[key] = obj[key].values
// or
// combined[key] = [obj[key].values] // in distinct arrays
}
}
}
return combined
}
var original=[{"key":"SAME KEY NAME","values":[1510148301000,34]},{"key":"SAME KEY NAME","values":[1509626301000,55]},{"key":"SAME KEY NAME","values":[1509539901000,62]},{"key":"DIFFERENT KEY NAME","values":[1509453501000,58]}];
var result=[];
var isAlreadyAdded=false;
original.forEach(function(outerObj){
var newObj={};
var values=[];
original.forEach(function(element) {
if(newObj["key"] !== outerObj.key){
newObj["key"]=element.key;
values=[];
values.push(element["values"]);
}else if(outerObj.key ===element.key ){
values.push(element["values"]);
}
});
newObj["values"]=values;
var count=0;
result.push(newObj);
});
var temp=[];
result=result.filter((x, i)=> {
if (temp.indexOf(x.key) < 0) {
temp.push(x.key);
return true;
}
return false;
})
console.log(result);

Return Multidimensional Array

I want to return a multiply dimensional array from a function like so but I must be writing it wrong, I cant figure out whats wrong. I want to have key and value pairs.
function Multidimensional(){
return [
"one": [
"two":[],
"three":[
"testing.png":{source:"http..."}
],
"another.png": {source:"http..."}
];
}
If you want to have key/value pairs, you should use an object.
function Multidimensional(){
return {
"one": {
"two":[],
"three":{
"testing.png":{source:"http..."}
},
"another.png": {source:"http..."}
};
}
You can access the returned data like so:
var data = Multidimensional();
console.log(data['another.png']);
// or
console.log(data.one);

Categories