How to format the element inside an array? - javascript

I have three arrays for example:
var name = ["wheel", "rectangle", "moon"];
var type = ["car", "shape", "sky"];
var all = [];
var temp = " ";
for (var i = 0; i < name.length; i++) {
temp = name[i] + " " + type[i];
all.push(temp);
}
for (var i = 0; i < name.length; i++) {
// I call here function to display all element of array `all`
}
The output is:
wheel car
rectangle shape
moon sky
But the format of output is not nice. I want to shift the element of array type before add them to array all, so I want the output to be like:
wheel car
rectangle shape
moon sky
My question is: how can I shift elements of the array to add them to another array and store them in a way that allows to me to display the elements like form above ?

But the form of output not nice
If you simply want to format the output in a better way, then try console.table
var name1 = [ "wheel","rectangle","moon" ];
var type = [ "car" , "shape", "sky"];
var all=[];
for (var i = 0; i< name1.length; i++)
{
all.push({ name : name1[i], type: type[i] });
}
console.table(all);
Try this fiddle to see the actual output since stack-snippet alters the behaviour of console api

You should calculate which is the longest string in the first array so to know in advance how many spaces you need to append to correctly pad the string
var n = ["wheel", "rectangle", "moon"];
var t = ["car", "shape", "sky"];
var all = [];
/* sorting the values of the first array by length desc,
* then get the length of the first element
*/
var padding = n.sort(function(a, b) {
return a.length <= b.length;
})[0].length + 1;
n.forEach(function(el, i) {
all.push(el + " ".repeat(padding - el.length) + t[i]);
});
Output
"rectangle car"
"wheel shape"
"moon sky"
codepen demo

First loop over the array and find the max length. Then loop again and add spaces.
<script >
var name=["wheel","rectangle","moon"];
var type=["car","shape","sky"];
var all=[];
var i=0;
var maxLength=0;
string temp=" ";
String.prototype.padLeft= function(len, c){
var r = '';
while(r.length < len) r += c;
return s+r;
}
for (i = 0; i< name.length; i++)
{
maxLength = Math.max(maxLength, name[i].length+type[i].length+1;
}
for (i = 0; i< name.length; i++)
{
temp=name[i]+type[i].padLeft(maxLength-name[i].length-type[i].length);
all.push(temp);
}
</script >

I would do as follows;
var id = ["wheel","rectangle","moon"],
type = ["car","shape","sky"];
id.longestStringLength = Math.max(...id.map(s => s.length));
type.longestStringLength = Math.max(...type.map(s => s.length));
id = id.map((s,_,a) => s + " ".repeat(a.longestStringLength-s.length));
type = type.map((s,_,a) => " ".repeat(a.longestStringLength-s.length) + s);
console.log(id,type);

Use \t instead of space while concatenating to make it aligned.

Why don't you just add tab '\t' and it will give you the desired output. Or you can append fixed number of spaces between the two array items.

Related

I have a string with counts and alphabets in ordered manner i have to print the alphabets according to their count

var input = `2
6
z2k1o2
6
m2v1p2`
var newInput = input.split("\n")
//console.log(newInput.length)
var input_arr = input.trim().split("\n")
var n = Number(input_arr[0])
//console.log(input_arr)
for (var i = 1; i < input_arr.length; i = i + 2) {
var length = Number(input_arr[i])
var string = input_arr[i + 1].trim()
}
//console.log(string)
var newstring = string
//console.log(newstring)
var alpha = []
var num = []
for (i = 1; i < string.length; i += 2) {
num.push(string[i])
}
var newnum = num.map(Number)
//console.log(newnum)
for (i = 0; i < string.length; i += 2) {
alpha.push(string[i])
}
var newalpha = (alpha)
//console.log(newalpha)
var answer = []
for (i = 0; i < newnum.length; i++) {
for (j = 0; j < newnum[i]; j++) {
answer.push(newalpha[i])
}
}
console.log(answer.join(""))
Here I'm getting only one output can you please explain why And do you like share any other approach for this problem.
This is the input z2k1o2 and the output should be zzkoo
The input will follow this patter of alphabets ans counts..
I'd do this with a regular expression that captures pairs of (character, number) and uses the function-replacement mode of .replace() to generate the replacement string.
> "a2b1c2".replace(/([a-z])([0-9]+)/ig, (_, a, b) => a.repeat(+b))
"aabcc"
>"pos2es2".replace(/([a-z])([0-9]+)/ig, (_, a, b) => a.repeat(+b))
"possess"
Here's where you're running into your error:
for (var i = 1; i < input_arr.length; i = i + 2) {
var length = Number(input_arr[i])
var string = input_arr[i + 1].trim()
}
You're going through the entire input array and saving each of the lengths and strings, but you're overwriting the length and the string each time you read it - only the last length and last string are saved, and so only the last length and last string are processed / printed.

Perform a merge on two strings

I'm trying to build a collaborative doc editor and implement operational transformation. Imagine we have a string that is manipulated simultaneously by 2 users. They can only add characters, not remove them. We want to incorporate both of their changes.
The original string is: catspider
The first user does this: cat<span id>spider</span>
The second user does this: c<span id>atspi</span>der
I'm trying to write a function that will produce: c<span id>at<span id>spi</span>der</span>
The function I've written is close, but it produces c<span id>at<span i</span>d>spider</span> codepen here
String.prototype.splice = function(start, newSubStr) {
return this.slice(0, start) + newSubStr + this.slice(start);
};
function merge(saved, working, requested) {
if (!saved || !working || !requested) {
return false;
}
var diffSavedWorking = createDiff(working, saved);
var diffRequestedWorking = createDiff(working, requested);
var newStr = working;
for (var i = 0; i < Math.max(diffRequestedWorking.length, diffSavedWorking.length); i++) {
//splice does an insert `before` -- we will assume that the saved document characters
//should always appear before the requested document characters in this merger operation
//so we first insert requested and then saved, which means that the final string will have the
//original characters first.
if (diffRequestedWorking[i]) {
newStr = newStr.splice(i, diffRequestedWorking[i]);
//we need to update the merge arrays by the number of
//inserted characters.
var length = diffRequestedWorking[i].length;
insertNatX(diffSavedWorking, length, i + 1);
insertNatX(diffRequestedWorking, length, i + 1);
}
if (diffSavedWorking[i]) {
newStr = newStr.splice(i, diffSavedWorking[i]);
//we need to update the merge arrays by the number of
//inserted characters.
var length = diffSavedWorking[i].length;
insertNatX(diffSavedWorking, length, i + 1);
insertNatX(diffRequestedWorking, length, i + 1);
}
}
return newStr;
}
//arr1 should be the shorter array.
//returns inserted characters at their
//insertion index.
function createDiff(arr1, arr2) {
var diff = [];
var j = 0;
for (var i = 0; i < arr1.length; i++) {
diff[i] = "";
while (arr2[j] !== arr1[i]) {
diff[i] += arr2[j];
j++;
}
j++;
}
var remainder = arr2.substr(j);
if (remainder) diff[i] = remainder;
return diff;
}
function insertNatX(arr, length, pos) {
for (var j = 0; j < length; j++) {
arr.splice(pos, 0, "");
}
}
var saved = 'cat<span id>spider</span>';
var working = 'catspider';
var requested = 'c<span id>atspi</span>der';
console.log(merge(saved, working, requested));
Would appreciate any thoughts on a better / simpler way to achieve this.

Text Analysis webpage does not work

For a homework assignment, I have to make a web page that has a text area. The user inputs some text, hits the analyse button, and the output is supposed to be a list of the frequency of words of a given number of characters. For example, "one two three" would be two words of three characters and one word of five characters. The text area works fine, but I can"t seem to get the output to appear.
Here is the html:
<body>
<textarea id="text" rows="26" cols="80"></textarea>
<form>
<input type="button" id="analyse" value="Analyse Text">
</form>
<div id="output"></div>
</body>
The JavaScript file has 6 functions. The first function returns an array that stores the number of characters for each word in the input textarea:
function getWordInfo() {
var text = document.getElementById("text").value;
//the variable wordArray uses a regular expression to parse the input
var wordArray = text.split("/\w\w+/g");
var arrayLength = wordArray.length;
var charArray = [];
for (var i = 0; i < arrayLength; i++) {
var splitWord = wordArray[i].split("");
var wordLength = splitWord.length;
charArray.push(wordLength);
}
return charArray;
}
The second function is a simple object constructor that has a name property and a count property. The count property has a default value of 0.
function obCon(name,count) { //object constructor
this.name = name;
this.count = count;
count = typeof count !== "undefined" ? count : 0;
}
The third function returns an array that stores word objects. Each object has a name property and a count property. The name property is the number of characters in a word. The count property counts how many times an object with a given name property appears.
function arCon() { //array constructor
var charNum = getWordInfo();
var arrayLength = charNum.length;
var obArr = [];
for (var i = 0; i < arrayLength; i++) {
if (typeof obArr.indexOf( newOb.name === charNum[i] ) != "undefined" ) { // checks if the object needed exists
obArr.indexOf( newOb.name === charNum[i] ).count = obArr.indexOf( newOb.name === charNum[i] ).count + 1;
}else{
var newOb = new obCon(charNum[i]);
newOb.count = newOb.count + 1;
obArr.push(newOb);
}
}
return obArr;
}
The fourth function is a string formatter, meant format the objects from arCon into a single readable string, then store it in an array.
function formatter() {
var strAr = arCon();
var arrayLength = strAr.length;
var formatStr = [];
for (var i = 0; i < arrayLength; i++) {
var str = "Number of characters: " + strAr[i].name + ", Number of words with this length: " + strAr[i].count;
formatStr.push(str);
}
return formatStr;
}
The fifth function is called for an event handler, meant to handle the click of the analyse button. On click, it is meant to get the div tag, get the formatted array, then loop though each element in the array, where it creates a p element element, pulls the formatted string, sets the p element value to the formatted string, then appends the p element to the div tag.
function analyseButtonClick() {
var div = document.getElementById("output");
var str = formatter();
var arrayLength = str.length;
for (var i = 0; i < arrayLength; i++) {
var par = document.createElement("p");
var format = str[i];
par.value = format;
div.appendChild(par);
}
}
The sixth function is an init function that handles the button click.
function init() {
var button = document.getElementById("analyse");
button.onclick = analyseButtonClick;
}
window.onload = init;
I have run this though a validator, and it shows me that there are no syntax errors, so it must be a logic error. However, all the functions seem to do what they are supposed to do, so I am not sure where I went wrong.
edit1: ok, have replaced the third function with four new functions. a function that returns the highest number in the array returned by getWordInfo, a function that constructs objects with name properties from 2 up to that number, a function that update the count properties of the objects, and a function that removes unused objects. here they are:
function maxNum() {
var array = getWordInfo();
var num = Math.max.apply(Math, array);
return num;
}
function objArrCon() { //object array constructor
var num = maxNum();
var array1 = [];
for (var i = 2; i === num; i++) {
var myObj = new objCon(i,0);
array1.push(myObj);
}
return array1;
}
function objArrParse() { //updates the object with word info
var array1 = getWordInfo();
var array2 = objArrCon();
var loopLength1 = array1.length;
var loopLength2 = array2.length;
for (var i = 0; i < loopLength1; i++) {
for (var m = 0; m < loopLength2; m++) {
if (array2[m].name === array1[i]) {
array2[m].count++;
}
}
}
return array2;
}
function objArrTrun() { //removes unused objects
var array1 = objArrParse();
var loopLength = array1.length;
for (var i = 0;i < loopLength; i++) {
if (array1[i].count === 0) {
array.splice(i, array1);
}
}
return array1;
}
still does not work, but im getting there!
I have written this in jQuery because 1) it's not my homework assignment and 2) it would be good practice (for you) to translate it back into normal JavaScript. You'll need to rewrite the event handler, along with the two getters/setters ($("text area").val() and $("tbody").append()).
Your main problem is that you have made your solution too complicated! If all you want to do is display the number, Y, of words with length, X, then you should do the following:
Grab the value of the text area and store in text
Remove all non-alphanumeric characters.
Split the text string wherever one or more spaces is present and store it in text
Loop through the array and map each array element, based on its length, to wordMap
Loop through wordMap and append it to wherever in the DOM you want the results to be
fiddle
JavaScript
$("#analyze").click(function () {
var text = $("textarea").val().replace(/[^\d\w ]+/g," ").split(/[ ]+/);
// this grabs the value of the text area, replaces all non-numerical
// and non-alphabetical characters with "", and then splits it into an array
// wherever one or more spaces is present.
var wordMap = {};
// makes an object that will be used as an associative array
text.forEach(function (d) {
// loops through the array
// if there is no key called d.length in wordMap
if (!wordMap[d.length])
wordMap[d.length] = 1; // set its count to one
else
wordMap[d.length]++; //otherwise, increment it
})
// loop through all the properties of wordMap
for (var x in wordMap) {
$("tbody").append("<tr><td>" + x + "</td><td>"
+ wordMap[x] + "</td></tr");
}
console.log(wordMap);
})
HTML
<textarea placeholder="type something..."></textarea>
<button id="analyze">Click to analyze</button>
<div id="results">
<table>
<thead>
<th>Length of Word</th>
<th>Number of Occurrences</th>
</thead>
<tbody>
</tbody>
</table>
</div>

Match a range of rows in an array? jQuery, Javascript

I'm unsure how else to write the title but it's about as close as I can get to what I'm after.
I have a calculator I'm trying to create that compares values in a number of arrays.
Each data object in my array has 34 rows, some of which have the same number/value in them.
At the minute if you select france, I only want 1 of each grade to show in the dropdown, so the number 1 would appear once.
If you select France and grade 1, I want the outputted value to say the lowest value in that range to the highest, in this case USA would output 3 to 5 does this make sense?
If so I'm wondering how I'd possibly do this?
JSFiddle
http://jsfiddle.net/R85Qj/
Does this help?
http://jsfiddle.net/R85Qj/2/
$("#convert").on("click", function () {
var gradeIndex = $("#grade").val();
var gradeConversion = "";
/* gradeConversion += "<span>" + countryGrades[countryGradesIndex].country + ": " + countryGrades[countryGradesIndex].grades[gradeIndex][1] + "</span>";*/
var indexes = [];
var countryIndex = $("#country").val();
var gradeValue = countryGrades[countryIndex].grades[gradeIndex][0];
// find all indexes of gradeValue
for(var i = 0; i < countryGrades[countryIndex].grades.length; i++) {
if (countryGrades[countryIndex].grades[i][1] == gradeValue) {
indexes.push(i);
}
}
allValues = [];
for(var c = 0; c < countryGrades.length; c++) {
gradeConversion += countryGrades[c].country + ":";
for(i = 0; i < indexes.length; i++) {
if (i == 0 || countryGrades[c].grades[indexes[i]][1] != countryGrades[c].grades[indexes[i-1]][1]) {
gradeConversion += countryGrades[c].grades[indexes[i]][1] + " ";
}
}
}
$("#conversions").html(gradeConversion);
});

Create array based on instance of delimiter/square-brackets

I have a string and I wanna create an array with even occurrence of "[]"
"Match[0][a][5][b][0][d][2]"
I want to split them and make an array using this string on the basis of instance of "[]". Each element of the array must have 2 occurrence of "[]" and the next element has two more occurrence of"[]". In another words I wanna create an array with even occurrence of "[]"
I want to make an array from string like:
["Match[0]['a']", "Match[0]['a'][5]['b']", "Match[0]['a'][5]['b'][0]['d']"]
Using javascript/jQuery
I have tried match but I only got it as far as this.
// ['part1.abc', 'part2.abc', 'part3.abc', 'part4']
'part1.abc.part2.abc.part3.abc.part4'.match(/[^.]+(\.[^.]+)?/g);
You can get the individual pieces in your array and then manipulate the result until it has the form you want. An example could be this one:
var str = "Match[0][a][5][b][0][d][2]";
var result = [];
str.split(/[\]\[]{1,2}/).slice(0,-1).reduce(function(acc,item, index) {
acc += '[' + (isNaN(item) ? "'" + item + "'" : item) + ']';
if (index %2 === 0 && index !== 0) {
result.push(acc);
}
return acc;
});
console.log(result) // ["Match[0]['a']", "Match[0]['a'][5]['b']", "Match[0]['a'][5]['b'][0]['d']"]
You can get each bracket with match(/\[.\]/g) and then composes your arrays by adding two by two.
var matches = "Match[0][a][5][b][0][d][2]".match(/\[(.)\]/g);
var result = [];
for (var i = 0; i < matches.length; i += 2) {
var brackets = '';
for(var j = 0; j< i; j++) {
brackets += matches[j];
}
result.push("Match" + brackets);
}
result.shift();
Wow its fun :) ... trying api and see how everyone is solving it. This is what i tried see if this is helpful.
str = "STR[1][3][4d][re]"
var re=/\[\w+\]/g;
var mat = str.match(re);
var ar = [];
for(i=2; i<= mat.length; i=i+2){
ar[ar.length] = "STR" + mat.slice(0,i).join("")
}
console.dir(ar)

Categories

Resources