2D Array to JsTree compatible JSON - javascript

I currently have a javascript function that accepts 1 dimensional arrays and adds them to a tree object.
var tree = {}
function addToTree(tree, arr) {
for (var i = 0, length = arr.length; i < length - 1; i++) {
tree = tree[arr[i]] = tree[arr[i]] || {};
}
tree[arr[i]] = null;
}
addToTree(tree, ["a", "b", "c", "f"])
addToTree(tree, ["a", "b", "d", "h", "l"])
I was hoping someone could help me format it so that it returns the object into a JSTree compatible object found here: https://www.jstree.com/docs/json/

For each element in the array ["a", "b", "c", "f"] you first need to create a node (one compatible to JSTree) and then add that node to the json object tree which we are building.
function createTreeNode(value) {
return {'text': value};
}
Now the function addToTree can be
var tree = {'core': {'data': []}}; //This initialization is needed
function addToTree(tree, arr) {
for (var i = 0; i < arr.length; i++) {
node = createTreeNode(arr[i]);
tree.core.data.push(node);
}
}
addToTree(tree, ["a", "b", "c", "f"]);
addToTree(tree, ["a", "b", "d", "h", "l"]);
BTW: In case you are using BootStrap consider jonmiles tree

Related

Get only values from a map (which has values as array) to an array typescript

I want to get values of a map (which has values as array) and store inside a string array in typescript.
myMap = {0:['a','b','c'], 1:['d','e'], 2:['f','g']};
Expected Result arr['a','b','c','d','e','f','g']
Updated: I haven't used flat() function before. Without flat() function it gives below result.
myMap = { 0: ["a", "b", "c"], 1: ["d", "e"], 2: ["f", "g"] };
const result = Object.values(myMap);
console.log(result);
Get all values of object using Object.values and then flat the array.
myMap = { 0: ["a", "b", "c"], 1: ["d", "e"], 2: ["f", "g"] };
const result = Object.values(myMap).flat();
console.log(result);
get the key and valueArray. the iterate through the valueArray.
const myMap = {0:['a','b','c'], 1:['d','e'], 2:['f','g']};
var arr = [];
for (const [key, valueArr] of Object.entries(myMap)) {
for (var i = 0; i < valueArr.length; i++) {
arr.push(valueArr[i]);
}
}
console.log(arr);

My replace function works with array but not with HTML collection which is also an array. Why?

I am writting a function to replace the position of some HTML elements in the page. Should be simple and it goes like this :
let square = document.getElementById("SquareCharts").children;
let testArray = ["A", "b", "c", "d", "E", "f", "g"];
function Replace(arr, oldPosition, newPosition)
{
let store;
store = arr[newPosition];
arr[newPosition] = arr[oldPosition];
arr[oldPosition] = store;
return console.log(arr);
}
replace(testArray, 4, 0);
replace(square, 4, 0);
It works with testArray but it doesn't seem to have any effect on the HTML elements order. Why and what can I do to change the original DOM?
You need to clear the element's current children then append them again.
let square = document.getElementById("SquareCharts").children;
let testArray = ["A", "b", "c", "d", "E", "f", "g"];
function Replace(arr, oldPosition, newPosition)
{
let store;
store = arr[newPosition];
arr[newPosition] = arr[oldPosition];
arr[oldPosition] = store;
// clear children
square.innerHTML = '';
for(const element of arr) {
square.append(element);
}
return console.log(arr);
}
replace(testArray, 4, 0);
replace(square, 4, 0);
document.getElementById("SquareCharts").children returns a HTMLCollection. Although it is iterable using a for-loop, it is not an Array.
You can also do:
let square = Array.from(document.getElementById("SquareCharts").children);
so that you can get more functionality with Array's built-in methods.

change order of array based on another array

Let say we have our array like this:
let myArray = ["A", "B", "C", "D"]
What if we want to modify the order of elements in myArray based on modifier array so that, if myArray includes any element of modifier then we send that element to the end of the myArray
Like this:
let modifier = ["B"]
myArray = ["A", "C", "D", "B"] // B is sent to the end of myArray
And if we have this:
let modifier = ["A", "C"]
myArray = ["B", "D", "A", "C"] // A and C are sent to the end of the array
I have tried looping and checking each array element against another but it went complicated...
Any help would be greatly appreciated.
Very simple.
Step-1: Remove elements of modifier array from original array
myArray = myArray.filter( (el) => !modifier.includes(el) );
Step-2: Push modifier array into original array
myArray = myArray.concat(modifier)
Update
As per demands in comments by seniors :) If use case is to move multiple data:
var myArray = ["A", "A", "A", "B", "B", "B", "C", "D", "E"];
var modifier = ["A", "B"];
// get static part
staticArray = myArray.filter( (el) => !modifier.includes(el) );
// get moving part
moveableArray = myArray.filter( (el) => modifier.includes(el) );
// merge both to get final array
myArray = staticArray.concat(moveableArray);
console.log(myArray);
You could sort the array and move the items of modifier to the end of the array.
function sort(array, lastValues) {
var last = Object.fromEntries(lastValues.map((v, i) => [v, i + 1]));
return array.sort((a, b) => (last[a] || - Infinity) - (last[b] || - Infinity));
}
var array = ["A", "B", "C", "D"];
console.log(...sort(array, ["B"]));
console.log(...sort(array, ["A", "C"]));
Simply use this to get desired result
let myArray = ["A", "B", "C", "D"];
let modifier = ["A", "C"];
for(let i=0;i<modifier.length;i++){
if(myArray.includes(modifier[i])){
myArray.splice(myArray.indexOf(modifier[i]), modifier[i]);
myArray.push(modifier[i]);
}
}
console.log(myArray);

How to iterate a list reversely and stop with a condition with lodash?

I have a list with some items for example
["a", "b", "c", ..., "x", "y", "z"]
I would like to iterate it but from the end to beggining and push those items into a new variable, and stop when it has length == 3.
For that simple example I would like to have as result within my new var:
["z", "y", "x"]
I'm thinking of .reverse() my array and then iterate it with .each and push my items, but I believe there is a better way to do that with lodash, that I'm not finding.
Maybe I'm not knowing how to search.
Thanks in advance.
You can do it with the function "_.takeRightWhile" from lodash like the code below:
var arr = ["a", "b", "c", "x", "y", "z"];
var reverseArray = [];
_.takeRightWhile(arr, function(item){
reverseArray.push(item)
return reverseArray.length < 3
});
console.log(reverseArray);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.min.js"></script>
In plain Javascript you could use Array#slice with a negative count for getting a new array from the end and use Array#reverse for a reversed array.
var array = ["a", "b", "c", "x", "y", "z"],
result = array.slice(-3).reverse();
console.log(result);
For processing items, you could use Array#reduceRight.
var array = ["a", "b", "c", "x", "y", "z"],
result = array.slice(-3).reduceRight((r, a) => r.concat(a), []);
console.log(result);
Another solution that iterates the original array:
var arr = ["a", "b", "c", "x", "y", "z"], res=[], count=3;
if (count <= arr.length)
for (var i=0; i<count; i++) res.push(arr[arr.length-1-i]);
console.log(res);

Removing Element From Array of Arrays with Regex

I'm using regex to test certain elements in an array of arrays. If an inner array doesn't follow the desired format, I'd like to remove it from the main/outer array. The regex I'm using is working correctly. I am not sure why it isn't removing - can anyone advise or offer any edits to resolve this problem?
for (var i = arr.length-1; i>0; i--) {
var a = /^\w+$/;
var b = /^\w+$/;
var c = /^\w+$/;
var first = a.test(arr[i][0]);
var second = b.test(arr[i][1]);
var third = c.test(arr[i][2]);
if ((!first) || (!second) || (!third)){
arr.splice(i,1);
}
When you cast splice method on an array, its length is updated immediately. Thus, in future iterations, you will probably jump over some of its members.
For example:
var arr = ['a','b','c','d','e','f','g']
for(var i = 0; i < arr.length; i++) {
console.log(i, arr)
if(i%2 === 0) {
arr.splice(i, 1) // remove elements with even index
}
}
console.log(arr)
It will output:
0 ["a", "b", "c", "d", "e", "f", "g"]
1 ["b", "c", "d", "e", "f", "g"]
2 ["b", "c", "d", "e", "f", "g"]
3 ["b", "c", "e", "f", "g"]
4 ["b", "c", "e", "f", "g"]
["b", "c", "e", "f"]
My suggestion is, do not modify the array itself if you still have to iterate through it. Use another variable to save it.
var arr = ['a','b','c','d','e','f','g']
var another = []
for(var i = 0; i < arr.length; i++) {
if(i%2) {
another.push(arr[i]) // store elements with odd index
}
}
console.log(another) // ["b", "d", "f"]
Or you could go with Array.prototype.filter, which is much simpler:
arr.filter(function(el, i) {
return i%2 // store elements with odd index
})
It also outputs:
["b", "d", "f"]
Your code seems to work to me. The code in your post was missing a } to close the for statement but that should have caused the script to fail to parse and not even run at all.
I do agree with Leo that it would probably be cleaner to rewrite it using Array.prototype.filter though.
The code in your question would look something like this as a filter:
arr = arr.filter(function (row) {
return /^\w+$/.test(row[0]) && /^\w+$/.test(row[1]) && /^\w+$/.test(row[2]);
});
jsFiddle
I'm assuming it is 3 different regular expressions in your actual code, if they are all identical in your code you can save a little overhead by defining the RegExp literal once:
arr = arr.filter(function (row) {
var rxIsWord = /^\w+$/;
return rxIsWord.test(row[0]) && rxIsWord.test(row[1]) && rxIsWord.test(row[2]);
});

Categories

Resources