Converting a string into an array of arrays - javascript

I have a string of data which look like this
0E-11 GERBER CA 960350E-110.0215.500000000 0E-12 TEHAMA CA 960900E-11214.800000000
I want to convert this string into an array of arrays.
Please note that after every 4 elements this array should be divided into new array and the end result should look like this:
Desire Results:
this.tblData: Array(2)
0: ["0E-11,"GERBER", "CA", "960350E-110.0215.500000000"]
1:["0E-12", "TEHAMA", "CA" ,"960900E-11214.800000000"]
Thanks

You can use the remainder operator and a forEach loop on that string to build an array of arrays, where each nested array is created every n steps:
var result = [];
"0E-11 GERBER CA 960350E-110.0215.500000000 0E-12 TEHAMA CA 960900E-11214.800000000".split(" ").forEach(function(element, index, array) {
if( (index + 1) % 4 === 0) {
result.push([
array[index-3],
array[index-2],
array[index-1],
array[index]
]);
}
});
console.log(result);

You can use reduce for such purposes
let result = "0E-11 GERBER CA 960350E-110.0215.500000000 0E-12 TEHAMA CA 960900E-11214.800000000"
.split(" ") // split the string based on the spaces
.reduce((current, item) => {
if (current[current.length - 1].length === 4) {
// in case the result array has already 4 items in it
// push in a new empty array
current.push([]);
}
// add the item to the last array
current[current.length - 1].push(item);
// return the array, so it can either be returned or used for the next iteration
return current;
}, [ [] ]); // start value for current would be an array containing 1 array
console.log(result);
It starts by splitting your string by spaces, creating an array of the values, and then we can transform the result using the reduce function.
The reduce function will take the second parameter as a start value for the current argument, which will start as an array containing 1 empty array.
Inside the reducer it first check if the last item in the array has a length of 4, in case it does, add the next sub array to the array, and will then push the current item inside the last array.
The result will then be an array containing your arrays

There is no need to use modulus operator, simply increment the loop's counter by 4:
var original = [
'0E-11',
'GERBER',
'CA',
'960350E-110.0215.500000000',
'0E-12',
'TEHAMA',
'CA',
'960900E-11214.800000000'
];
var result = [];
for (var i = 0; i < original.length; i += 4) {
result.push([
original[i],
original[i+1],
original[i+2],
original[i+3],
]);
}
console.log(result);
Output: [ [ '0E-11', 'GERBER', 'CA', '960350E-110.0215.500000000' ],
[ '0E-12', 'TEHAMA', 'CA', '960900E-11214.800000000' ] ]
This assumes that the data is 4 element aligned.

Related

How to enter a string to an array to a given position?

The condition is such that I have to enter a string to an array to a given position
such that all the pre position if not exist should be made to be empty strings.
example;
var array = []; // now I want to enter a string 'hello' at index 2
now the array should look like:
array = [ '','','hello']; //now lets say I want to enter a string 'world' at index 4
so the array should become:
array = [ '','','hello','','world'];
Is there a way to do this?
or do i have a better option to enter a string and and its position?
Please enlighten me.. :)
Something like this should do the trick. The function takes three arguments: the target array, the index (0-based) and the value. Just iterate from the finish of you array to the new position and add "" to each entry, then, after the loop, enqueue the desired string. Here's the fiddle.
let a = ['', '', 'Hello'];
function addStringAtPosition(
array,
key,
value
) {
for (let i = array.length; i < key; i++) {
array[i] = '';
}
array[key] = value;
}
addStringAtPosition(a, 5, 'World!');
First find out how many additional elements need to add ''
push these new elements to array.
push the required value at end.
PS: Assumed the index always higher than the array length. We can add conditions to cover those cases as well.
const insert = (arr, value, index) => {
arr.push(...new Array(index - arr.length).fill(""));
arr.push(value);
return arr;
};
const array = [];
insert(array, "hello", 2);
console.log(array);
insert(array, "world", 4);
console.log(array);

What's the best way to split an array into multiple arrays every time an element is met?

I'm fairly new to JS and still learning. I have this array:
[A,true,B,true,C,true,D,true,E,A,true,B,true,C,false,E,A,true,B,false,E]
What's the best way to split said array into multiple arrays everytime E occurs?
ie. the above array becomes:
[A,true,B,true,C,true,D,true,E]
[A,true,B,true,C,false,E]
[A,true,B,false,E]
What I have tried:
I have tried converting the array into a string and splitting it, yet the result isn't satisfactory.
var pathsString = paths.toString();
pathsString = pathsString.split("," + end).filter(function(el) {return el.length != 0});
//end is E in this case
Thank you
You can use Array.reduce() and Array.filter():
const arr = ['A',true,'B',true,'C',true,'D',true,'E','A',true,'B',true,'C',false,'E','A',true,'B',false,'E'];
const result = arr.reduce((acc, x) => {
acc[acc.length-1].push(x)
if (x === 'E') acc.push([]);
return acc;
}, [[]]).filter(x => x.length);
console.log(result);
Here are some explanations:
Array.reduce() iterates over the an array and passes an accumulator from one iteration to the next. This accumulator (acc) is initialized to [[]] at the beginning (an array with an empty group).
At each iteration, we take the last group in acc and append the value x to that group.
If the value equals E, we also push a new empty group for the next iteration.
Then, we filter out the empty groups left out if E was the last letter or if the input array was empty.
You can chunk the array with Array.reduce():
const arr = ['A',true,'B',true,'C',true,'D',true,'E','A',true,'B',true,'C',false,'E','A',true,'B',false,'E']
const result = arr.reduce((r, c, i) => {
if(!i || c === 'E') r.push([]) // if it's the 1st item, or the item is E push a new sub array
r[r.length - 1].push(c) // push the item to the last sub array
return r
}, [])
console.log(result)
var original = ['A',true,'B',true,'C',true,'D',true,'E','A',true,'B',true,'C',false,'E','A',true,'B',false,'E'];
// make a copy of the original, just so we are not changing it
var temp = original.slice(0);
// the variable we will collect all the sub arrays in
var result = [];
// while the temp still has data to evaluate, loop
while (temp.length) {
// find the next position of the first character in the temp array
// add one since the index was affected by us slicing off the first character
var lastIndex = temp.slice(1).indexOf(temp[0]) + 1;
// if the lastIndex is not 0, add the sub array
if (lastIndex) {
// push the sub array
result.push(temp.slice(0, lastIndex));
// remove the sub array from temp so its not processed again
temp = temp.slice(lastIndex);
} else {
// index was zero, so the indexOf was -1 (not found), so it's the last subarray
result.push(temp);
// set to empty list so the loop ends
temp = [];
}
}
console.log(result);

array cross-over loop in javascript

let's say i have this code :
let variants = []
let variant = {
variantName: 'Size',
variantItems: ['XL','MD','SM']
}
variants.push(variant)
variant = {
variantName: 'Color',
variantItems: ['Red','Blue']
}
variants.push(variant)
okay, now how do i output it to something like this :
and the variants array can contain many variant object
and if there is one more object inside variants array :
variant = {
variantName: 'Material',
variantItems: ['Plastic','Wood', 'Ceramic']
}
variants.push(variant)
and it will be outputted like this :
Please help, i very appreciate your help...
You can use a recursive function with Array#map, and Array#concat to flatten the results:
const variants = [{"variantName":"Size","variantItems":["XL","MD","SM"]},{"variantName":"Color","variantItems":["Red","Blue"]},{"variantName":"Material","variantItems":["Plastic","Wood","Ceramic"]}];
const addVariants = (variants) => {
// destructure the 1st item array, and the rest of the variants
const add = ([{ variantName, variantItems }, ...variants], row = []) =>
// iterate the variants and flatten
[].concat(...variantItems.map((variantItem) => {
// create a new array for the current row, and the variant string
const currRow = [...row, `${variantName}: ${variantItem}`];
// if there are more variants, invoke add with the remaining variants and the current row, or join the array to a string (the end result)
return variants.length ? add(variants, currRow) : currRow.join(', '); // instead of currRow.join(', ') replace with [currRow] if you want an array
}));
return add(variants);
}
const result = addVariants(variants);
console.log(result);
This is a functional ES6 approach.
let variants = [{
variantName: "Size",
variantItems: [
"XL",
"MD",
"SM"
]
},
{
variantName: "Color",
variantItems: [
"Red",
"Blue"
]
}];
let crossJoined = new Array(variants.reduce((product, variant) => (product * variant.variantItems.length), 1))
.fill(0)
.reduce(crossJoin => {
crossJoin.data.push(crossJoin.currentIndexes.map((itemIndex, variantIndex) => `${variants[variantIndex].variantName}: ${variants[variantIndex].variantItems[itemIndex]}`).join(", "));
let incrementableIndex = variants.length - crossJoin.currentIndexes
.slice()
.reverse()
.findIndex((itemIndex, variantIndex) => variants[variants.length - variantIndex - 1].variantItems.length > itemIndex + 1) - 1;
crossJoin.currentIndexes[incrementableIndex]++;
crossJoin.currentIndexes = crossJoin.currentIndexes.map((value, index) => (index > incrementableIndex
? 0
: value));
return (crossJoin.currentIndexes.length == variants.length
? crossJoin
: crossJoin.data);
}, {
data: [],
currentIndexes: new Array(variants.length).fill(0)
}).join("\n");
console.log(crossJoined);
First, an array is created with a length of all variantItems array lengths multiplied, then it is zero-filled. Next, we reduce it to another array.
crossJoin is the aggregator that holds an object of this structure most of the time:
{
data: [ … ],
currentIndexes: [ 1, 3 ] // Corresponds to variants[0].variantItems[1]
// and variants[1].variantItems[3]
}
That is “most of the time”, until the end, where currentIndexes won’t be used anymore and only its data property is returned.
So in each reduce iteration, we first push a new entry to crossJoin.data, using crossJoin.currentIndexes and the indexes of that array. Removing .join(", ") will result in an entry of the structure
[ "Size", "XL" ]
Next, we need to increment the numbers in crossJoin.currentIndexes:
[ 0, 0 ] should be incremented to [ 0, 1 ], because there is a second color at the index 1. [ 0, 1 ] should be incremented to [ 1, 0 ], because there is no third color, but a second size, but then we need the first color again, and so on. The last valid index array is [ 2, 1 ] which corresponds to the third size and the second color, which is the last combination.
incrementableIndex is the last possible index that can still be incremented. Once incremented, all subsequent indexes have to be 0.
You see those variants.length - something - 1 twice, because you need to find the first index from the end, so you have to reverse (a copy of — hence the slice) the array, then re-interpret the found index as an index from the start again.
The return returns this crossJoin object for the next iteration. The condition crossJoin.currentIndexes.length == variants.length applies to the very end, where no index can be incremented anymore. It adds a NaN to the currentIndexes array, so the lengths don’t match, and instead of filtering out or preventing the NaN, I just ignored and discarded it altogether.
The output will be an array of all combinations. You can .join("\n") it to make a string where each combination is separated by a line-break, or you can use .forEach to append each combination to a list, for example.
Use .each loop on variants array. Take another array and add object using size, color and material. So it will become combined array of your requirement. Then print new array data as per requirement using .each loop .

javascript - multidimensional array contains 4 items but length indicates: 0

I made a multidimensional array today which creates 4 new arrays within the first array. when I console.log my array it says that there are 0 items in it, but i do see my 4 arrays each with other items. See the console.log below for a clearer image:
vm.allGroupsInClassifications = [];
datacontext.graph.getAllGroups().then(function (data) {
var groups = [];
// get all clasification names and put them in the array and create a new array
for (var k in vm.classificationNames) {
var groupName = vm.classificationNames[k];
groups[groupName] = new Array();
}
// go through all the groups and sort them based on their classification
for (var i = 0; i < data.length; i++) {
if (data[i].classification != null) {
modifyGroupContent(data[i], groups, 0);
}
else if (data[i].classification == null)
modifyGroupContent(data[i], groups, 1);
}
vm.allGroupsInClassifications = groups;
console.log(vm.allGroupsInClassifications);
any help would be appreciated. Cheers!
Because you have no indexes. groups[groupName] = new Array(); won't add an item to your array, because all your groupName variables are not numbers. And thus you have an array-object-like thing.
If your groupName's were say 0,1,2 and 3, when you console.log the object, you will get the last number+1 (in this case 4).
Here you can access your arrays with the keys - so in this case vm.allGroupsInClassifications['Confidential'] will return your array.
But since you don't have actual numeric indexes, the length of your object-array thing is 0.
Hope you understand
It's because your array is incorrect. You have an array with keys :
[
"Algemeen" : [...],
"Confidential" : [...]
]
This is incorrect, as arrays can't have keys. Javascript being Javascript, it allows you to define it nonetheless, but when you ask for its length, it's quite unable to answer and says 0. It should be an object :
{
"Algemeen" : [...],
"Confidential" : [...]
}
If you really want to keep an array of arrays, remove the keys :
[ [...],[...] ]
Now the length is 2.

How do I sort one array by the corresponding values in another array?

I have two arrays. The first is for strings and the second is an array for their number of occurrences.
I am trying to get the top 10 most occurrences of words in the first array. I sorted it but somehow I only sort it alphabetically and the second array respectively corresponds to their number of occurrences.
How can I sort the second array from biggest to lowest and, at the same time, sort the first array that match the order of the second?
I'm having trouble inserting my json to my highcharts and I found out why, the numbers should be in square brackets [] I tried already inserting [] in 1 but still does not work please see my post I edit it
this is the data that i should insert in the highchart
[{"name":"#murrayftw","data":[46]},
{"name":"#job","data":[37]},
{"name":"#jobs","data":[25]},
{"name":"#favnashvine","data":[16]},
{"name":"#rollersmusicawards","data":[14]},
{"name":"#soa","data":[13]},
{"name":"#tweetmyjobs","data":[12]},
{"name":"#sman1boyolangu","data":[12]},
{"name":"#supernatural200thepisode","data":[12]},
{"name":"#veteransday","data":[12]}]
Try using a custom compare function with your .sort() call! Check out the documentation here.
I would, in this example (probably not the best way):
Have the unsorted "count" array
Have the unsorted word array
Sort the word array (with a custom function described below)
Sort the count array (no custom function)
The custom compare function would probably be a simple lookup and return the corresponding value in the unsorted count array. (i.e. if the word "a" is 0th index and its relevant count amount is in the 0th index of the count array, return count[0])
If you cannot work with an object try using nested for loops:
var array1 = ['z', 'd', 'e', 'f', 't'], arr1Count = array1.length;
var array2 = [1, 12, 5, 7, 3];
var sortedArray2 = array2.sort(function(x, y) {return y - x});
var i, j, sortedArray1 = [];
for (i = 0; i < arr1Count; i++) {
for (j = 0; j < arr1Count; j++) {
if (array2[j] === sortedArray2[i]) sortedArray1.push(array1[j]); //iterate through the unsorted numeric array (array2) and when it matches the sortedArray2, push this index of array1 into the sortedArray1
}
}
This will create an array of objects that are then sorted by count.
var hashtags = {},
counts = [];
for (var i in data)
{
if(data[i].lang == "en")
{
for (var j in data[i].entities.hashtags)
{
var text = data[i].entities.hashtags[j].text;
if(text) {
if(hashtags[text]) {
hashtags[text].data[0]++;
} else {
hashtags[text] = {
name: text,
data: [1]
};
counts.push(hashtags[text]);
}
}
}
}
}
counts.sort(function(a, b) { return b.data[0] - a.data[0]; });
Simple - don't use 2 arrays but one collection which every element is an object
I took the basics from this post: Sorting JavaScript Object by property value
and completed the demo:
var collection = {car:300, bike:60, motorbike:200, airplane:1000, helicopter:400, rocket:8*60*60}
var sortable = [];
for (var item in collection)
sortable.push([item, collection[item]])
sortable.sort(function(a, b) {return a[1] - b[1]})
collection = {};
for (var i in sortable)
{
collection[sortable[i][0]] = sortable[i][1];
}
console.log(collection);

Categories

Resources