Flatten Nested Array Without Using Flatten Function - javascript

I'm currently stuck on a problem. I'm trying to make [[1,2,[3]],4] -> [1,2,3,4] but cannot get it to work. The output I keep getting is: 1,2,3,4
1,2,3
3
3
3
3..........3
function flattenArray(input) {
var result = [];
console.log(input.toString());
for(i = 0; i < input.length; i++) {
if(input[i].constructor === Array) {
result.push(flattenArray(input[i]));
} else {
result.push(input[i]);
}
}
return result;
}
console.log(flattenArray([[1,2,[3]],4]));

I have this in my common.js file. I use it all the time.
Array.prototype.flatten = function () {
var ret = [];
for (var i = 0; i < this.length; i++) {
if (Array.isArray(this[i])) {
ret = ret.concat(this[i].flatten());
} else {
ret.push(this[i]);
}
}
return ret;
};
Here it is as a function:
function flattenArray(input) {
console.log(input.toString());
var ret = [];
for (var i = 0; i < input.length; i++) {
if (Array.isArray(input[i])) {
ret = ret.concat(flattenArray(input[i]));
} else {
ret.push(input[i]);
}
}
return ret;
}

Related

$.when apply for single request

I am trying to use $.when apply in my code. However, it seems that the format return is different for single and multiple request. How can i cater for it?? I am trying not to have another if else outside of it.
$.when.apply(null, apiRequestList).then(function () {
for (var i = 0; i < arguments.length; i++) {
var value = arguments[0];
}
});
This is what i do not want to do.
if (apiRequestList.length === 1) {
$.ajax({
});
} else {
$.when.apply(null, apiRequestList).then(function () {
for (var i = 0; i < arguments.length; i++) {
var value = arguments[0];
}
});
}
You can simply convert arguments into an array, when the length of apiRequestList is 1:
$.when.apply(null, apiRequestList).then(function() {
var _arguments = Array.prototype.slice.call(arguments);
if (Array.isArray(apiRequestList) && apiRequestList.length === 1)
_arguments = [arguments];
for (var i = 0; i < _arguments.length; i++) {
var value = _arguments[i][0];
console.log(value);
}
});
Live Example on jsFiddle (since we can't do ajax on Stack Snippets):
function x(a) {
return $.post("/echo/html/", {
html: "a = " + a,
delay: Math.random()
});
}
function doIt(apiRequestList) {
$.when.apply(null, apiRequestList).then(function() {
var _arguments = arguments;
if (Array.isArray(apiRequestList) && apiRequestList.length === 1)
_arguments = [arguments];
for (var i = 0; i < _arguments.length; i++) {
var value = _arguments[i][0];
console.log(value);
}
console.log("----");
});
}
doIt([x(1), x(2), x(3)]);
doIt([x(4)]);
Example output (it'll vary because of the Math.random()):
a = 4
----
a = 1
a = 2
a = 3
----

How to use function outside $scope ( error: function isn't defined)

I have a rzslider which takes in true or false for disabled. I want disable to be true based on a function. So I want to make it disabled:$scope.truthy
I have a function called checkDupsName() checkDupsName should return true if there is a duplicate, false otherwise. I set my $scope.truthy variable to be true if the function returns true but the issue is, when I call it outside this function ( in my slider), it's ALWAYS false.
$scope.checkDupsName = function(Mylist) {
var i, j, n;
n = Mylist.length;
for (i = 0; i < n; i++) {
for (j = i + 1; j < n; j++) {
if (Mylist[i] === Mylist[j]) {
return true;
}
}
}
return false;
};
$scope.truthy=false;
$scope.nameList = [];
var Types = [];
$scope.loadRuleList = function() {
PrioritizeService.getData($scope.prioritizeURL).
then(function(response) {
if (response) {
Types = response;
}
for (var k = 0; k < Types.length; k++) {
$scope.nameList.push(Types[k].name);
}
if($scope.checkDupsName($scope.nameList)) {
$scope.truthy=true;
}
};
$scope.slider = {
value: 1,
options: {
floor: 0,
ceil: 3,
showTicks: true,
showTicksValues: true,
disabled:$scope.truthy
}
};
You are defining it inside of your function that is being called by then. You should move it outside and make it a function defined/declared on the scope instead and have it take the data it uses as a parameter.
// initialize it so your code does not blow up in the case of forgotten undefined or null check
$scope.nameList = [];
$scope.loadRuleList = function() {
var me = this;
PrioritizeService.getData($scope.MyURL).
then(function(response) {
if (response) {
Types = response;
}
// re-init the nameList field
me.nameList = [];
for (var k = 0; k < Types.length; k++) {
me.nameList.push(Types[k].name)
}
//check for duplicates
var areDups = me.checkDupsName(me.nameList);
}
}
$scope.checkDupsName = function(listToCheck) {
var i, j, n;
n = listToCheck.length;
for (i = 0; i < n; i++) {
for (j = i + 1; j < n; j++) {
if (listToCheck[i] === listToCheck[j]) {
return true;
}
}
}
return false;
}

How to print the items in q, the async way

Here is a program i'm trying wrap my head around with, how do i print the items in the q properly, once all the results are pushed ?
function asyncAdd(a,b,callback) {
setTimeout(function() {
return callback(a+b);
},0);
}
var q = [];
var ctr = 0;
for (var i=0; i<9; i++) {
(function(i) {
var res = asyncAdd(i, 0, printRes);
q.push(res);
})(i);
}
function done(q) {
console.log("done"+q);
}
function printRes(res) {
return res;
}
Please have a look at my version
function asyncAdd(a,b,callback) {
callback(a+b);
}
var q = [];
var ctr = 0;
var max = 9;
for (var i = 0; i < max; i++) {
asyncAdd(i, 0, printRes);
}
function done(q) {
console.log("done " + q);
}
function printRes(res) {
q.push(res);
if (q.length === max)
done(q);
}

I can't figure out why it's saying that the matcher function is undefined.

This code is designed to identify an array of anagrams for a string given an array of possible anagrams.
var anagram = function(input) {
return input.toLowerCase();
}
I'm adding the matcher function here to the String prototype.
String.prototype.matcher = function(remainingLetters) {
var clone = this.split("");
for (var i = 0; i < clone.length; i++) {
if (clone[i].indexOf(remainingLetters) > -1) {
remainingLetters.splice(clone[i].indexOf(remainingLetters, 1));
clone.splice(i, 1);
}
}
if (remainingLetters.length == 0 && clone.length == 0) {
return true;
}
else {
return false;
}
}
a
String.prototype.matches = function(matchWordArray) {
var result = [];
for (var i = 0; matchWordArray.length; i++) {
var remainingLetters = this.split("");
if (matchWordArray[i].matcher(remainingLetters)) {
result.push(arrayToMatch[i]);
}
}
return result;
}
var a = anagram("test");
a.matches(["stet", "blah", "1"]);
module.exports = anagram;
Should probably be:
for (var i = 0; i < matchWordArray.length; i++) {
The original statement:
for (var i = 0; matchWordArray.length; i++) {
...would result in an infinite loop because matchWordArray.length is always truthy (3) in your test.

Is there a single function to check an array contains another array?

[1,2,3].CONTAINS([1,2]) ==> true
[1,2,3].CONTAINS([1,2,3,4]) ==> false
or
{a:1,b:2,c:3}.HASKEYS([a,b]) ==> true
{a:1,b:2,c:3}.HASKEYS([a,b,c,d]) ==> false
Is there a single function to check an array contains another array?
No, but you can make one:
Array.prototype.contains = function(other) {
for (var i = 0; i < other.length; i++) {
if (this.indexOf(other[i]) === -1) return false;
}
return true;
}
And if order matters:
Array.prototype.contains = function(other) {
var broken;
if (!other.length) return true;
for (var i = 0; i < this.length - other.length + 1; i++) {
broken = false;
for (var j = 0; j < other.length; j++) {
if (this[i + j] !== other[j]) {
broken = true;
break;
}
}
if (!broken) return true;
}
return false;
}
The other function is similar, so I'll leave it to you to finish:
Object.prototype.has_keys = function(keys) {
...
}

Categories

Resources