Looping through a recursive array [closed] - javascript

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 6 years ago.
Improve this question
I've got a recursive array. So the array below can go deeper and deeper.
0: "1"
1: [
0: "2"
1: [
0: "3"
]
2: [
0: "4"
1: [
0: "5"
]
]
]
I want the output to be the path of all the values. So 123 and 1245.
How can this be done in a Javascript method?

You need a recursive method to flatten a recursive array.
Here's a pretty basic one:
var data = ["1",
[
"2",
[
"3"
],
[
"4",
[
"5"
]
]
]];
var flattened = [];
function flatten(data, outputArray) {
data.forEach(function (element){
if(Array.isArray(element)) {
flatten(element, outputArray);
} else {
outputArray.push(element);
}
});
}
flatten(data, flattened);
This should get you moving in the right direction. Good luck!

I am not sure, but what you have presented looks more like an object. In such case it is quite easy to traverse through the nested object, eg.
var object = { 0: "1",
1: {
0: "2",
1: {
0: "3"
},
2: {
0: "4",
1: {
0: "5"
}
}
}};
console.info(object);
function traverse(obj) {
obj.keys.forEach(function(key) {
if (typeof(obj[key]) === 'object') {
traverse(obj[key])
}
else {
//do something with the actual value
console.log(obj[key])
}
})
};
traverse(object)
Can you specify what did you mean with I want the output to be the path of all the values?

You could try lodash:
_.flattenDeep([1, [2, [3, [4]], 5]]);
// => [1, 2, 3, 4, 5]
https://lodash.com/docs/4.17.2#flattenDeep
but I'm not sure of your example data; you said an array but it looks (almost) like an object, in which case you'd have to first convert this to array. Again, lodash is your friend!
If you don't want to use lodash you could try something like this:
var results = [];
function flatten(arr) {
arr.forEach(function(item) {
if (Array.isArray(item)) {
flatten(item);
}
else {
results.push(item);
}
})
}
flatten(data);
Fiddle
Edit after comment by Nina Scholz
It looks like the OP has an object with keys '0', '1', '2' etc, each of which may contain a recursive array. So the code above would have to be executed on the data associated with each key and the results appended to the value of the key to get 123, 1245 etc.

Related

How to add a new object to another within an array [duplicate]

This question already has answers here:
How to append something to an array?
(30 answers)
Closed 2 years ago.
I have an array which looks like this:
array = [
{code1:
{
number: 2,
name: "e"
}
},
{code2:
{
number:2,
name: "u"
}
}
]
and I want to add the following as a new object to say "code1" without changing the data it now has.
{
number: 3,
name: "j"
}
how can I do it? Thank you!
1st approach
If I understood what you want to do correctly this could work:
array = [
{code1:
{
number: 2,
name: "e"
}
},
{code2:
{
number:2,
name: "u"
}
},
{code1:
{
number: 3,
name: "j"
}
}
];
2nd approach
However this would make the structure more difficult to traverse. As an alternative you could make the whole thing into a dictionary of arrays, like this:˛
let object = {//doesn't matter what we call it
code1:[
{
number:2,
name: "e"
},
{
number:3,
name: "j"
}
],
code2:[
{
number:2,
name: "u"
}
]
};
You'd go about accessing the new object like this: console.log(object.code1[0].number);
You can try this approach out in the snippet bellow.
let object = {//doesn't matter what we call it
code1:[
{
number:2,
name: "e"
},
{
number:3,
name: "j"
}
],
code2:[
{
number:2,
name: "u"
}
]
};
console.log(object.code1[0].number);
Closing statement
But as I've already said, I'm not sure if I understood your question correctly, I'd suggest editting the question to make it clearer in the future.
Thanks for reading
Internet person out.

Swap elements in array with various data types [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 2 years ago.
Improve this question
So I was looking around SO for an answer, and I did get some insight, but can't quite get to a desired solution. My issue is this:
So I have a keypad with number 1 through 5, and when I select one of the number keys, it moves it to an array called numberPad, as an object, like so:
[
{ number: 1, alias: 'one', checked: true, option: 'Option for key 1' },
{ number: 4, alias: 'four', checked: true, option: 'Option for key 4' }
]
And then it renders each index of numberPad as a styled card, and each number is its own clickable dropdown button. When clicking on the rendered number, a separate list of buttons (* also 1 through 5*) becomes visible, and if, on that new list of buttons, a number is clicked that is not in the numberPad array, then that data is pushed to numberPad. If the number exists in numberPad, this where I need to make something happen...
So let's say 1 and 4 are rendered, and I click on the number 4 to open the list of buttons. If I now select 1, since it is already in the data array, I want to swap just the option value between the two.
So, I click on 4, the button list opens, and I click on 1, I want my array to look like this:
[
{ number: 1, alias: 'one', checked: true, option: 'Option for key 4' },
{ number: 4, alias: 'four', checked: true, option: 'Option for key 1' }
]
I am having some trouble getting there. I have seen many answers on SO about a swap function, but those seem to swap the entire index with another index, where as I only want to swap one key/value pair on a click.
Does anyone have any advice here please...? Thanks in advance!!
Ok, so I feel silly. I already had this swap function that I wrote:
swapArray = (input, i, j) => {
// do not mutate original array
const copyArray = input.slice(0);
[copyArray[i], copyArray[j]] = [copyArray[j], copyArray[i]];
return copyArray;
};
All I had to do was extend the function like so:
swapArray = (input, i, j, data) => {
// do not mutate original array
const copyArray = input.slice(0);
[copyArray[i][data], copyArray[j][data]] = [copyArray[j][data], copyArray[i][data]];
return copyArray;
};
Then all I had to do for my above numberPad array is:
swapArray(numberPad, 0, 1, 'option')
And it yields the correct result. No idea how I didn't realize that right away. Mods, feel free to close this question please...
I'm assuming that the objects will be the input from the array which you mentioned in the question and made the changes accordingly. I'm mutating the same data object based on the requirement. Hope this function help you with what you are looking for.
let data = [
{
"number": 1,
"alias": "one",
"checked": true,
"option": "Option for key 1"
},
{
"number": 4,
"alias": "four",
"checked": true,
"option": "Option for key 4"
}
]
let swapOptions = (clickedObj, selectedObj) => {
const selectedObjIndex = data.findIndex(d => d.number === selectedObj.number)
if(selectedObjIndex === -1) {
data.push(selectedObj);
return;
}
clickedObjIndex = data.findIndex(d => d.number === clickedObj.number)
data.splice(clickedObjIndex, 1, {...clickedObj, option: selectedObj.option})
data.splice(selectedObjIndex, 1, {...selectedObj, option:clickedObj.option})
}
swapOptions(data[1], data[0])
console.log(data)
swapOptions(data[0], {
"number": 5,
"alias": "one",
"checked": true,
"option": "Option for key 5"
})
console.log(data)

JSON Object to Arrays [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 4 years ago.
Improve this question
Below JSON Object needs to be iterated and need result as below.
[
{"Aazam":1, "Jagannath":2, "Bharath Kumar M":4 },
{"Bharath Kumar M":1, "Syad":1 },
{"Bharath Kumar M":2 }
]
output needed (can be in map):
Aazam: 1
Jagannath: 2
Bharath Kumar M: 4, 1, 2
Syad: 1
I tried with ES 6 syntax, I am able to get key and values but I am not successful in forming the array as needed.
Solution should be generic.
You can have a object as a output with the unique keys and values for each key as an array that holds the values of all similar keys.
var arr = [{
"Aazam": 1,
"Jagannath": 2,
"Bharath Kumar M": 4
},
{
"Bharath Kumar M": 1,
"Syad": 1
},
{
"Bharath Kumar M": 2
}
];
var res = arr.reduce((acc, item) => {
var keys = Object.keys(item);
keys.forEach((key) => {
if (!acc[key]) {
acc[key] = [];
}
acc[key].push(item[key]);
});
return acc;
}, {});
console.log(res);

Javascript create array of Object property values

Given this Object in Javascript
{
"0": "hello",
"1": { text: "world" }
}
What's the shortest way to create this array from that object?
[
"hello",
{ text: "world" }
]
I've seen somebody using Array.prototype.splice(theObject) but it doesn't seem to work for me.
Update:
Order of output needs to be guaranteed
0 and 1 can be any arbitrary string value and the order at property level needs to be maintained in the corresponding array.
Needs to work with Node.js 6
Just use Object.values:
console.log(Object.values({
"0": "hello",
"1": { text: "world" }
}));
If you want to be sure that the original keys of the object correspond to the positions in the resulting array, you can't rely on Object.values() or a for ... in loop. You can use Object.keys() and sort that array.
var keys = Object.keys(yourObject);
keys.sort();
var array = keys.map(key => yourObject[key]);
Now understand that the call to .sort() can include a comparator function to impose any ordering desired on the original object keys. The sample in the OP is very simple, and the above would work. However more complicated keys might require a custom comparator.
This should maintain the order based on the keys, including where keys have more than one digit
const test = {
"0": "hello",
"3": "three",
"1": { text: "world" },
"2": "two",
"11": "eleven",
}
const transform = obj => Object.keys(obj)
.sort((a, b) => parseInt(a) > parseInt(b) ? 1 : -1)
.map(key => obj[key])
console.dir(transform(test))
let src = {
"0": "hello",
"1": {
text: "world"
}
}
let res = [src].map(it => [it['0'], it['1']])
console.log(res)
Try using for..in loop like this:
let obj = {
"0": "hello",
"1": { text: "world" }
}
let result = []
for(var value in obj){
result.push(obj[value])
}

Sort array of objects by quarterly-yearly data in JavaScript [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 6 years ago.
Improve this question
I have an array of data containing objects like below
[
{
"name":"Q1'2016",
"y":0
},
{
"name":"Q2'2016",
"y":0
},
{
"name":"Q3'2016",
"y":0
},
{
"name":"Q4'2015",
"y":0
}
]
I want to sort them based on quarterly, so Q4'2015 should come first, then Q1'2016 and so on.
How can this be acheived?
You can use the sort method and give it a callback to sort your object based on a predicate; in your case, you want to inspect the objects' name property containing your quarter-year information. Since you'll likely have data with different quarters and years, you'll want to map the quarters to month values so you can convert them to year/month dates and compare them that way.
var data = [{
"name": "Q1'2016",
"y": 0
}, {
"name": "Q2'2016",
"y": 0
}, {
"name": "Q3'2016",
"y": 0
}, {
"name": "Q4'2015",
"y": 0
}];
var quarterToMonthMap = {
"Q1": 0,
"Q2": 3,
"Q3": 6,
"Q4": 9
}
function sortByQuarterYear(lhs, rhs) {
var lhsQuarterYear = lhs.name.split("'");
var rhsQuarterYear = rhs.name.split("'");
var lhsDate = new Date(lhsQuarterYear[1], quarterToMonthMap[lhsQuarterYear[0]]);
var rhsDate = new Date(rhsQuarterYear[1], quarterToMonthMap[rhsQuarterYear[0]]);
return lhsDate.getTime() - rhsDate.getTime();
}
document.write(JSON.stringify(data.sort(sortByQuarterYear)));
To sort by year and quarter you can use the following ES6 snippet (you can do the exact same thing using ES5, but I like writing ES6)
input.map((obj, index) => obj.name.split("'").reverse().concat(index)).sort().map(arr => input[arr[2]]);
Let's break this down a bit
input.map((obj, index) => obj.name.split("'").reverse().concat(index))
The map() method creates a new array with the results of calling a provided function on every element in this array.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map
Our "provided function" splits the "name" property of each object by the ' character, reverses the resulting array, and adds the current index into the resulting array.
This results in an array that looks like this:
[
["2016", "Q1", 0],
["2016", "Q2", 1],
["2016", "Q3", 2],
["2015", "Q4", 3]
]
Then we call .sort,
The sort() method sorts the elements of an array in place and returns the array. The sort is not necessarily stable. The default sort order is according to string Unicode code points.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort
We then end up with an array like this:
[
["2015", "Q4", 3],
["2016", "Q1", 0],
["2016", "Q2", 1],
["2016", "Q3", 2]
]
So we now have an appendix of sorts, notice that the indexes that we threw in there aren't in order. We can use this lack of order to create order.
All we have to do is call map again, this time returning the original object related to the index that we have stored in our temporary arrays.
.map(arr => input[arr[2]]);
When we put it all together and call it, we end up with an array like this:
[
{
name: "Q4'2015",
y: 0
}, {
name: "Q1'2016",
y: 0
}, {
name: "Q2'2016",
y: 0
}, {
name: "Q3'2016",
y: 0
}
]
Here's a demo:
let input = [
{
"name":"Q1'2016",
"y":0
},
{
"name":"Q2'2016",
"y":0
},
{
"name":"Q3'2016",
"y":0
},
{
"name":"Q4'2015",
"y":0
}
];
input = input.map((obj, index) => obj.name.split("'").reverse().concat(index)).sort().map(arr => input[arr[2]]);
console.log(input);
To do the exact same thing in ES5:
input.map(function(obj, index){
return obj.name.split("'").reverse().concat(index);
}).sort().map(function(arr){
return input[arr[2]];
});
Using .sort() with a comparator function, you can easily re-format each value from "Q1'2016" to "2016Q1", allowing a simple alphanumeric comparison because "2016Q1" > "2015Q4".
function sortQuarters(arr) {
function reformat(v) {
return v.replace(/(Q\d)'(\d{4})/, "$2$1");
}
return arr.sort(function(a, b) {
return reformat(a.name).localeCompare(reformat(b.name));
});
}
console.log(sortQuarters([
{ "name":"Q1'2016", "y":0 },
{ "name":"Q3'2016", "y":0 },
{ "name":"Q2'2016", "y":0 },
{ "name":"Q4'2015", "y":0 }
]));
(Note that the reformatting I'm talking about is only within temporary variables used while sorting, it doesn't change the values in the array. Also note that the function I've shown modifies the order of the array passed to it and returns back the same array, it doesn't create a new array.)

Categories