Related
Create a function that accepts a string and groups repeated values. The groups should have the following structure: [[value, first_index, last_index, times_repeated], ..., [value, first_index, last_index, times_repeated]].
value: Character being assessed.
first_index: Index of characters first appearance.
last_index: Index of characters last appearance.
times_repeated: Number of consecutive times character repeats.
Examples
findRepeating("a") ➞ [["a", 0, 0, 1]]
findRepeating("aabbb") ➞ [["a", 0, 1, 2], ["b", 2, 4, 3]]
findRepeating("1337") ➞ [["1", 0, 0, 1], ["3", 1, 2, 2], ["7", 3, 3, 1]]
findRepeating("aabbbaabbb") ➞ [["a", 0, 1, 2], ["b", 2, 4, 3], ["a", 5, 6, 2], ["b", 7, 9, 3]]
I am able to do it for unique characters.
But unable to do it for
Number of consecutive times character repeats
MY CODE
function findRepeating(str) {
let unique = [...new Set([...str])]
return unique.map(x=>[x,str.indexOf(x),str.lastIndexOf(x),[...str].filter(a=>a==x).length])
}
EXPECTED RESULT
Test.assertSimilar(findRepeating(''), [])
Test.assertSimilar(findRepeating('a'), [['a', 0, 0, 1]])
Test.assertSimilar(findRepeating('1337'), [['1', 0, 0, 1], ['3', 1, 2, 2], ['7', 3, 3, 1]])
Test.assertSimilar(findRepeating('aabbb'), [['a', 0, 1, 2], ['b', 2, 4, 3]])
Test.assertSimilar(findRepeating('addressee'), [['a', 0, 0, 1], ['d', 1, 2, 2], ['r', 3, 3, 1], ['e', 4, 4, 1], ['s', 5, 6, 2], ['e', 7, 8, 2]])
Test.assertSimilar(findRepeating('aabbbaabbb'), [['a', 0, 1, 2], ['b', 2, 4, 3], ['a', 5, 6, 2], ['b', 7, 9, 3]])
Test.assertSimilar(findRepeating('1111222233334444'), [['1', 0, 3, 4], ['2', 4, 7, 4], ['3', 8, 11, 4], ['4', 12, 15, 4]])
Test.assertSimilar(findRepeating('1000000000000066600000000000001'), [['1', 0, 0, 1], ['0', 1, 13, 13], ['6', 14, 16, 3], ['0', 17, 29, 13], ['1', 30, 30, 1]])
ACTUAL RESULT
Test Passed: Value == '[]'
Test Passed: Value == "[['a', 0, 0, 1]]"
Test Passed: Value == "[['1', 0, 0, 1], ['3', 1, 2, 2], ['7', 3, 3, 1]]"
Test Passed: Value == "[['a', 0, 1, 2], ['b', 2, 4, 3]]"
FAILED: Expected: "[['a', 0, 0, 1], ['d', 1, 2, 2], ['r', 3, 3, 1], ['e', 4, 4, 1], ['s', 5, 6, 2], ['e', 7, 8, 2]]", instead got: "[['a', 0, 0, 1], ['d', 1, 2, 2], ['r', 3, 3, 1], ['e', 4, 8, 3], ['s', 5, 6, 2]]"
FAILED: Expected: "[['a', 0, 1, 2], ['b', 2, 4, 3], ['a', 5, 6, 2], ['b', 7, 9, 3]]", instead got: "[['a', 0, 6, 4], ['b', 2, 9, 6]]"
Test Passed: Value == "[['1', 0, 3, 4], ['2', 4, 7, 4], ['3', 8, 11, 4], ['4', 12, 15, 4]]"
FAILED: Expected: "[['1', 0, 0, 1], ['0', 1, 13, 13], ['6', 14, 16, 3], ['0', 17, 29, 13], ['1', 30, 30, 1]]", instead got: "[['1', 0, 30, 2], ['0', 1, 29, 26], ['6', 14, 16, 3]]"
function findRepeating(str) {
let unique = [...new Set([...str])]
return unique.map(x=>[x,str.indexOf(x),str.lastIndexOf(x),[...str].filter(a=>a==x).length])
}
console.log("Fails ",JSON.stringify(findRepeating('addressee')),"\nexpected", `[['a',0,0,1],['d',1,2,2],['r',3,3,1],['e',4,4,1],['s',5,6,2],['e',7,8,2]]`)
console.log("Fails ",JSON.stringify(findRepeating('aabbbaabbb')),"\nexpected", `[['a',0,1,2],['b',2,4,3],['a',5,6,2],['b',7,9,3]]`)
console.log("Passes ",JSON.stringify(findRepeating('1111222233334444')),"\nexpected", `[['1',0,3,4],['2',4,7,4],['3',8,11,4],['4',12,15,4]]`)
console.log("Fails ",JSON.stringify(findRepeating('1000000000000066600000000000001')),"\nexpected", `[['1',0,0,1],['0',1,13,13],['6', 14,16,3],['0',17,29,13],['1',30,30,1]]`)
You could take an array of same characters with a regular expression which looks for a character and same following onces as a group and map the wanted information.
function findRepeating(string) {
var i = -1;
return (string.match(/(.)\1*/g) || []).map(s => [s[0], ++i, i += s.length - 1, s.length]);
}
console.log(findRepeating("")); // []
console.log(findRepeating("a")); // [["a", 0, 0, 1]]
console.log(findRepeating("aabbb")); // [["a", 0, 1, 2], ["b", 2, 4, 3]]
console.log(findRepeating("1337")); // [["1", 0, 0, 1], ["3", 1, 2, 2], ["7", 3, 3, 1]]
console.log(findRepeating("aabbbaabbb")); // [["a", 0, 1, 2], ["b", 2, 4, 3], ["a", 5, 6, 2], ["b", 7, 9, 3]]
Your code assumes that each group is about a different character. As soon as you have two groups with the same character, things like lastIndex will give the wrong result.
Just use a plain for-loop.
function findRepeating(str) {
let result = [];
let start = 0;
for (let i = 0; i < str.length; i++) {
if (str[i] !== str[i+1]) {
result.push([str[i], start, i, i-start+1]);
start = i+1;
}
}
return result;
}
console.log(findRepeating(''), [])
console.log(findRepeating('a'), [['a', 0, 0, 1]])
console.log(findRepeating('1337'), [['1', 0, 0, 1], ['3', 1, 2, 2], ['7', 3, 3, 1]])
console.log(findRepeating('aabbb'), [['a', 0, 1, 2], ['b', 2, 4, 3]])
console.log(findRepeating('addressee'), [['a', 0, 0, 1], ['d', 1, 2, 2], ['r', 3, 3, 1], ['e', 4, 4, 1], ['s', 5, 6, 2], ['e', 7, 8, 2]])
Hi i have a problem when code, I want to check an even number in multidimensional array and then change to 'X' if there are even numbers in row or column more than equals to 3 times appear but I change it all to 'X' eventhough it's less than 3. my code like this :
function evenNumbers(numbers){
for(var i = 0; i < numbers.length; i++){
for(var j = 0; j < numbers[i].length; j++){
if(numbers[i][j] % 2 == 0){
numbers[i][j] = 'X'
}
}
}
return numbers
}
console.log(evenNumbers([
[1, 2, 4, 6, 5],
[6, 17, 8, 11, 10],
[8, 11, 10, 18, 16],
[18, 12, 19, 27, 21],
[22, 10, 12, 22, 12]
]));
expected output :
[1, 'X', 'X', 'X', 5],
['X', 17, 'X', 11, 10],
['X', 11, 'X', 'X', 'X'],
['X', 12, 19, 27 , 21],
[''X, 'X', 'X', 'X', 'X']
what I got :
[ [ 1, 'X', 'X', 'X', 5 ],
[ 'X', 17, 'X', 11, 'X' ],
[ 'X', 11, 'X', 'X', 'X' ],
[ 'X', 'X', 19, 27, 21 ],
[ 'X', 'X', 'X', 'X', 'X' ] ]
Thanks, in advance
Help me with no ES6 built-in just regular JS, please. Thanks again
You could use some to make the check, then map
const arr = [
[1, 2, 4, 6, 5],
[6, 17, 8, 11, 10],
[8, 11, 10, 18, 16],
[18, 12, 19, 27, 21],
[22, 10, 12, 22, 12]
];
function xEvens(arr) {
return arr.map(row => {
let i = 0;
let shouldChange = row.some(n => n % 2 === 0 && ++i >= 3);
return shouldChange ? row.map(n => n % 2 === 0 ? 'X' : n) : row;
});
}
console.log(xEvens(arr));
Pre es6 version
var arr = [
[1, 2, 4, 6, 5],
[6, 17, 8, 11, 10],
[8, 11, 10, 18, 16],
[18, 12, 19, 27, 21],
[22, 10, 12, 22, 12]
];
function xEvens(arr) {
return arr.map(function(row) {
var i = 0;
var shouldChange = row.some(function(n) {
return n % 2 === 0 && ++i >= 3;
});
return shouldChange ? row.map(function(n) {
return n % 2 === 0 ? 'X' : n
}) : row;
});
}
console.log(xEvens(arr));
You can try following approach:
Idea:
Loop on array and return an array where X is replaced for even numbers.
Keep a track of count of replacements.
If count matches the threshold, return this new array.
If not, return the original array.
This way you will not need an extra loop just to check the validity for replacement.
function replaceEvensWithCondition(arr, minCount, replaceChar) {
return arr.map(function(row) {
var count = 0;
var updatedArray = row.map(function(n) {
var isEven = n % 2 === 0;
count += +isEven;
return isEven ? replaceChar : n;
});
return count >= minCount ? updatedArray : row
});
}
var arr = [ [1, 2, 4, 6, 5], [6, 17, 8, 11, 10], [8, 11, 10, 18, 16], [18, 12, 19, 27, 21], [22, 10, 12, 22, 12] ];
console.log(replaceEvensWithCondition(arr, 3, 'X'));
I'm so frustrated with a project I working on in which if there are duplicate elements in a table I want to hide them. I find the duplicates without a problem. The issues starts when I try to hide the duplicates. I'm using vanilla JavaScript without any frame works or libraries. I get this error that is really hard to decipher.
Uncaught Type Error: Cannot read property 'e' of undefined
e is first duplicate element in the table
I don't have any hard coded data in my HTML - it's all JavaScript. I have never done a display none this way before so I thought I would reach out for some help. My code is below.
Appreciating Your Help In Advance.
var data = [
['e', 0, 1, 2, 3, 4],
['a', 54312, 235, 5, 15, 4],
['a', 6, 7, 8, 9, 232],
['a', 54, 11235, 345, 5, 6],
['b', 0, 1, 2, 3, 4],
['b', 54312, 235, 5, 15, 4],
['c', 62, 15, 754, 93, 323],
['d', 27, 11235, 425, 18, 78],
['d', 0, 1, 2, 3, 4],
['d', 54312, 235, 5, 15, 4],
['e', 6, 7, 8, 9, 232],
['e', 54, 11235, 345, 5, 6],
['e', 0, 1, 2, 3, 4],
['e', 54312, 235, 5, 15, 4],
['e', 62, 15, 754, 93, 323],
['e', 27, 11235, 425, 18, 78]
];
//Create a HTML Table element.
var table = document.createElement("TABLE");
var elems = document.getElementsByClassName("tableRow");
//Get the count of columns.
var columnCount = data[0].length;
//Add the data rows.
for (var i = 0; i < data.length; i++) {
var row = table.insertRow(-1);
for (var j = 0; j < columnCount; j++) {
//Searching for duplicates
var num = data[i][0];
for (var otherRow = i + 1; otherRow < data.length; otherRow++) {
var dup = data[otherRow][0];
console.log("What is the dup" + dup);
if (num === dup) {
console.log("duplicate");
elems.data[dup].style.display = "none";
}
}
var cell = row.insertCell(-1);
cell.innerHTML = data[i][j];
cell.innerHtml = myZero;
}
}
var dvTable = document.getElementById("dvTable");
dvTable.innerHTML = "";
dvTable.appendChild(table);
You can separate the de-duplication and actually creating the elements from your data. Using Array.filter you can remove all duplicates so you don't have to worry about that when you do the inserting.
var data = [
['e', 0, 1, 2, 3, 4],
['a', 54312, 235, 5, 15, 4],
['a', 6, 7, 8, 9, 232],
['a', 54, 11235, 345, 5, 6],
['b', 0, 1, 2, 3, 4],
['b', 54312, 235, 5, 15, 4],
['c', 62, 15, 754, 93, 323],
['d', 27, 11235, 425, 18, 78],
['d', 0, 1, 2, 3, 4],
['d', 54312, 235, 5, 15, 4],
['e', 6, 7, 8, 9, 232],
['e', 54, 11235, 345, 5, 6],
['e', 0, 1, 2, 3, 4],
['e', 54312, 235, 5, 15, 4],
['e', 62, 15, 754, 93, 323],
['e', 27, 11235, 425, 18, 78]
];
var alreadyFound = [];
data = data.filter(function(item, pos, arr) {
var key = item[0];
// If we have already found this character, then skip.
if (alreadyFound.indexOf(key) > -1) return false;
// Otherwise, add this char to alreadyFound and include the item.
alreadyFound.push(key);
return true;
});
//Create a HTML Table element.
var table = document.createElement("TABLE");
var elems = document.getElementsByClassName("tableRow");
//Get the count of columns.
var columnCount = data[0].length;
//Add the data rows.
for (var i = 0; i < data.length; i++) {
var row = table.insertRow(-1);
for (var j = 0; j < columnCount; j++) {
var cell = row.insertCell(-1);
cell.innerHTML = data[i][j];
}
}
var dvTable = document.getElementById("dvTable");
dvTable.innerHTML = "";
dvTable.appendChild(table);
<div id="dvTable"></div>
I agree with Red Mercury. you first need to remove duplicates in your array.
Red Mercury answer is perfectly valid but here is a dirty quick multi-dimensional array deduplication function I am using for such stuff.
var data = [
['e', 0, 1, 2, 3, 4],
['a', 54312, 235, 5, 15, 4],
['a', 6, 7, 8, 9, 232],
['a', 54, 11235, 345, 5, 6],
['b', 0, 1, 2, 3, 4],
['b', 54312, 235, 5, 15, 4],
['c', 62, 15, 754, 93, 323],
['d', 27, 11235, 425, 18, 78],
['d', 0, 1, 2, 3, 4],
['d', 54312, 235, 5, 15, 4],
['e', 6, 7, 8, 9, 232],
['e', 54, 11235, 345, 5, 6],
['e', 0, 1, 2, 3, 4],
['e', 54312, 235, 5, 15, 4],
['e', 62, 15, 754, 93, 323],
['e', 27, 11235, 425, 18, 78]
];
function multiDimlUniq(arr) {
var uniques = [];
var founds = {};
for (var i = 0, l = arr.length; i < l; i++) {
var s = JSON.stringify(arr[i]);
if (founds[s]) {
continue;
}
uniques.push(arr[i]);
founds[s] = true;
}
return uniques;
}
var reduced = multiDimlUniq(data)
I am facing an issue with array ordering sequence. Need your help for desired result.
var a = [0, 1, 2, 3, 4, 5, 6, 77, 7, 8, 9, 10, 11, 12, 35, 36, 43, 51, 72, 89, 95, 100];
var b = [6,5,7,8,0,800,46,1,2,3,12,47,100,95];
var c = [];
for (var i = 0; i <= (a.length) - 1; i++) {
var res = b.indexOf(a[i]);
if (res > -1) {
c.push(a[i]);
}
}
document.write(c);
// I need same sequence of array B in reponse
// Desired Result
// 6,5,7,8,0,1,2,3,12,100,95
Iterate array b instead of a:
var a = [0, 1, 2, 3, 4, 5, 6, 77, 7, 8, 9, 10, 11, 12, 35, 36, 43, 51, 72, 89, 95, 100];
var b = [6,5,7,8,0,800,46,1,2,3,12,47,100,95];
var c = [];
for (var i = 0; i < b.length; i++) {
var res = a.indexOf(b[i]);
if (res > -1) {
c.push(b[i]);
}
}
console.log(c.join(','));
A more functional solution is to use Array#filter on b:
var a = [0, 1, 2, 3, 4, 5, 6, 77, 7, 8, 9, 10, 11, 12, 35, 36, 43, 51, 72, 89, 95, 100];
var b = [6,5,7,8,0,800,46,1,2,3,12,47,100,95];
var c = b.filter(function(n) {
return a.indexOf(n) !== -1;
});
console.log(c.join(','));
I currently have the following array set up:
var TicketInfo =
{
t1: {
1: [7, 12, 35,39,41, 43],
2: [7, 15, 20,34,45, 48],
3: [3, 7, 10, 13, 22, 43],
4: [2, 4, 5,23,27, 33]
},
t2: {
1: [10, 12, 17,44,48, 49],
2: [13, 15, 17, 18, 32, 39],
3: [16, 17, 20, 45, 48, 49],
4: [6, 16, 18, 21, 32, 40]
}
}
What I want to do is iterate through these to bring back the arrays under.
As a test I've tried something like this:
for(t in TicketInfo["t1"])
{
i++;
Write(t.i);
}
But it's obviously not working how I want it to.
Any ideas?
I want to be able to output the arrays like [7, 12, 35,39,41, 43]
Thanks
var TicketInfo =
{
t1: {
1: [7, 12, 35,39,41, 43],
2: [7, 15, 20,34,45, 48],
3: [3, 7, 10, 13, 22, 43],
4: [2, 4, 5,23,27, 33]
},
t2: {
1: [10, 12, 17,44,48, 49],
2: [13, 15, 17, 18, 32, 39],
3: [16, 17, 20, 45, 48, 49],
4: [6, 16, 18, 21, 32, 40]
}
}
for(var j in TicketInfo )
{
for(var p in TicketInfo[j] )
{
for(var i = 0; i < TicketInfo[j][p].length; i++ )
{
console.log(TicketInfo[j][p][i]);
}
}
}
http://jsfiddle.net/J6rTj/
If you're here from google trying to find a way to do a quick print for debugging, here's a one liner for you:
console.log(myArray.join("\n"))
Example:
var myArray = [[1,2,3],[4,5,6],[7,8,9]];
console.log(myArray.join("\n"));
Output:
1,2,3
4,5,6
7,8,9
Example with proper brackets:
var myArray = [[1,2,3],[4,5,6],[7,8,9]];
console.log("[[" + myArray.join("],\n[") + "]]");
Output:
[[1,2,3],
[4,5,6],
[7,8,9]]
Answer to OP's question:
obj = {
1: [7, 12, 35,39,41, 43],
2: [7, 15, 20,34,45, 48],
3: [3, 7, 10, 13, 22, 43],
4: [2, 4, 5,23,27, 33],
}
var keys = Object.keys(obj);
keys.sort();
console.log(keys);
var listFromObj = []
for (var i = 0; i < keys.length; i++) {
if (obj.hasOwnProperty(keys[i])) listFromObj.push(obj[keys[i]]);
}
console.log("[" + listFromObj.join("]\n[") + "]");
Output:
[7,12,35,39,41,43]
[7,15,20,34,45,48]
[3,7,10,13,22,43]
[2,4,5,23,27,33]
The syntax is TicketInfo["t1"]["1"][0].
That example will give you 7.
TicketInfo["t1"]["1"] will give you the array you're after at the base of your question.
In your code t just represents the key.
Try following code:
var TicketInfo =
{
t1: {
1: [7, 12, 35,39,41, 43],
2: [7, 15, 20,34,45, 48],
3: [3, 7, 10, 13, 22, 43],
4: [2, 4, 5,23,27, 33]
},
t2: {
1: [10, 12, 17,44,48, 49],
2: [13, 15, 17, 18, 32, 39],
3: [16, 17, 20, 45, 48, 49],
4: [6, 16, 18, 21, 32, 40]
}
}
for(t in TicketInfo["t1"])
{
i++;
console.log(TicketInfo["t1"][t]);
}
Do I understand that you want to output entire table in order? Since you use objects on t1/t2 level, you'll have to do extra steps for that.
First, see if you can simply replace objects with real arrays:
var TicketInfoArrays = {
t1: [
[7, 12, 35,39,41, 43],
[7, 15, 20,34,45, 48],
[3, 7, 10, 13, 22, 43],
[2, 4, 5,23,27, 33]
]
}
var t1 = TicketInfoArrays.t1
for(var idx = 0, len = t1.length; idx<len; idx++){
var line = idx+": ["
var nested = t1[idx]
for(var idx2 = 0, len2 = nested.length; idx2<len2; idx2++){
line += ((idx2 > 0 ? ', ':'') + nested[idx2])
}
console.log(line + ']')
}
If that's somehow impossible, but you sure that keys in those objects always start at some specific number and go ascending without gaps, you can simply itreate over properties until you hit empty element:
var TicketInfo = {
t1: {
1: [7, 12, 35,39,41, 43],
2: [7, 15, 20,34,45, 48],
3: [3, 7, 10, 13, 22, 43],
4: [2, 4, 5,23,27, 33]
}
}
var t1 = TicketInfo.t1
var idx = 1
var nested
while(nested = t1[idx]){
var line = idx+": ["
var nested = t1[idx]
for(var idx2 = 0, len2 = nested.length; idx2<len2; idx2++){
line += ((idx2 > 0 ? ', ':'') + nested[idx2])
}
console.log(line + ']')
idx++
}
Finally, if you can't guarantee even that, you will have to manually collect all keys, sort them and then iterate over this sorted list.
var TicketInfoUnordered = {
t1: {
8: [7, 12, 35,39,41, 43],
20: [7, 15, 20,34,45, 48],
45: [3, 7, 10, 13, 22, 43],
3: [2, 4, 5,23,27, 33]
}
}
var t1 = TicketInfoUnordered.t1
var keys = []
for(key in t1){
if(t1.hasOwnProperty(key)){ keys.push(key) }
}
keys.sort(function(a, b){ return a - b })
for(var idx = 0, len = keys.length; idx<len; idx++){
var line = keys[idx]+": ["
var nested = t1[keys[idx]]
for(var idx2 = 0, len2 = nested.length; idx2<len2; idx2++){
line += ((idx2 > 0 ? ', ':'') + nested[idx2])
}
console.log(line + ']')
}