I implemented a search function and loop that search by collection. In first iteration I need to search by all collection, but all next iterations only by result of the first iteration. I use if-statement if (i >= 1) collection = result; to do it, but it's not safe because I need to save collection. Is it possible to rewrite loop to recursion function? How I can make it or make my code elegant?
var targets = target.split(' '); // => ['hello', 'world'];
for (var i = 0; i < targets.length; ++i) {
if (i >= 1) {
collection = result;
}
result = includes(collection, props, targets[i]);
}
My search function:
function includes(collection, props, target) {
var result = [];
var collection_length = collection.length;
var props_length = props.length;
var target_length = target.length;
for (var i = 0; i < collection_length; ++i) {
for (var j = 0; j < props_length; ++j) {
if (collection[i][props[j]]) {
if (collection[i][props[j]].toLowerCase().slice(0, target_length) === target) {
result.push(collection[i]);
continue;
}
}
}
}
return result.length !== 0 ? result : false;
}
var result = collection;
for (var i = 0; i < targets.length; ++i) {
result = includes(result, props, targets[i]);
}
Maybe I'm missing something but isn't this what you're trying to do?
Related
Here is my code sans input
// Check if three addends equal sum and return the product if so
let result;
function addNumbers(first,second,third,sum) {
if (first + second + third === sum) {
result = first * second * third;
return (first * second * third);
}
};
// find three numbers in list that add up to specific number
function testResult(list,sum) {
let firstAddend;
let secondAddend;
let thirdAddend;
for (let i = 0; i < list.length; i++) {
firstAddend = list.shift();
for (let j = 0; j < list.length; j++) {
secondAddend = list[j];
for (let k = 1; k < list.length; k++) {
thirdAddend = list[k];
addNumbers(firstAddend,secondAddend,thirdAddend,sum);
}
}
}
};
What I want is testResult() to return the result from addNumbers() when it returns the product. I want to get rid of let result; and result = ... in addNumbers(). I've been confused about scope but I think I'm starting to understand. Does each for loop contain the scope of the previous? If anyone is interested this is from Advent of Code Day 1. I am not certain if having the data is necessary here. If it is let me know and I will edit accordingly.
Does each for loop contain the scope of the previous?
Yes, it does. Whenever you create a sub-scope, all the variables in the previous scope are available. So, you don't actually have to declare firstAddend and secondAddend and thirdAddend ahead of time:
function testResult(list,sum) {
for (let i = 0; i < list.length; i++) {
let firstAddend = list.shift();
for (let j = 0; j < list.length; j++) {
let secondAddend = list[j];
for (let k = 1; k < list.length; k++) {
let thirdAddend = list[k];
addNumbers(firstAddend,secondAddend,thirdAddend,sum);
}
}
}
}
Next, the return means that when you call the function, it takes on the value that you return. So, you don't need a global result variable, as you can just utilize the return value. However, you should move the if statement out of the addNumbers function and into the testResult function, as you need to know when to return, not just what to return. In fact, the addNumbers function is simply enough to where it should just go directly into testResult:
function testResult(list,sum) {
for (let i = 0; i < list.length; i++) {
let firstAddend = list.shift();
for (let j = 0; j < list.length; j++) {
let secondAddend = list[j];
for (let k = 1; k < list.length; k++) {
let thirdAddend = list[k];
if (firstAddend + secondAddend + thirdAddend === sum) {
return firstAddend * secondAddend * thirdAddend;
}
}
}
}
}
For practice, if you want the function, you could do something like the following:
function addNumbers(first,second,third,sum) {
if (first + second + third === sum) {
return (first * second * third);
} else {
return null; // return some value so the calling function knows that no sum was found
}
}
function testResult(list,sum) {
for (let i = 0; i < list.length; i++) {
let firstAddend = list.shift();
for (let j = 0; j < list.length; j++) {
let secondAddend = list[j];
for (let k = 1; k < list.length; k++) {
let thirdAddend = list[k];
let result = addNumbers(firstAddend, secondAddend, thirdAddend, sum);
if (result !== null) {
return result;
}
}
}
}
}
when I alert this I only get the last value of id. ican't findout where I'm going wrong
$scope.addToList = function (products,qty) {
if ($scope.order.length > 0) {
for (var i = 0; i < $scope.order.length; i++) {
$scope.Thx=$scope.order[i].id;
}}};
alert($scope.Thx);
Declare the $scope.Thx as an array first.
$scope.Thx = [];
$scope.addToList = function (products, qty) {
if ($scope.order.length > 0) {
for (var i = 0; i < $scope.order.length; i++) {
$scope.Thx.push($scope.order[i].id);
}
}
};
This line will overwrite the $scope.Thx for each iteration inside the loop.
$scope.Thx=$scope.order[i].id;
Now there are two ways to get the desired result.
1. If you want the separate alert for each item in the array then:
$scope.addToList = function (products,qty) {
if ($scope.order.length > 0) {
for (var i = 0; i < $scope.order.length; i++) {
$scope.Thx=$scope.order[i].id;
alert($scope.Thx);
}}};
2. If you want single alert for all the items.
declare $scope.Thx as an array first.
$scope.Thx = [];
$scope.addToList = function (products, qty) {
if ($scope.order.length > 0) {
for (var i = 0; i < $scope.order.length; i++) {
$scope.Thx.push($scope.order[i].id);
}
}
};
var tempVar="";
for(var i=0; i<$scope.Thx.length;i++)
{
tempVar += $scope.Thx[0]+"\n";
}
alert(tempVar);
When i loop through the array using the splice method, the page just freezes. It looks like i caused an infinite loop. lib.randomInt() works, so that is not the problem.
function() {
return function(string) {
var arr = string.split("")
arr.sort();
for(var i = 0; arr.length;i++){
arr.splice((i+1),0,lib.randomInt(9));
}
var pseudocryptarr = arr.join("");
}
})()("example");
This is from a different file that is placed above the main file in html
var lib = {
factorial: function(num){
function _factorial(num){
if(num === 1){
return 1;
} else {
return num*_factorial(num-1);
}
}
console.log(num+"! = " + _factorial(num));
},
randomInt: function(int,offset){
if(offset == undefined || null || NaN){
offset = 0;
}
return Math.floor(Math.random()*int)+offset;
},
display: function(m, fn){
fn(m);
}
};
You've got to loop in reverse when modifying the array itself to avoid corrupting the loop like this...
for (var i=arr.length-1; i>=0; i--){}
I guess that you wanted to insert a random value after every array element, so that the string "example" would become something like "e5x9a2m4p7l1e3"
There are two issues:
Your for loop has no end condition that will become false. You need to state i < arr.length instead of just arr.length which is always truthy for non-empty arrays.
You add array elements in every iteration, but then also visit them in the next iteration, and from there on you will only be visiting the new inserted values and never get to the next original element that keeps being 1 index away from i. You need to increment i once more. For that you can use ++i instead if i+1 as the splice argument.
So your loop should be:
for(var i = 0; i < arr.length; i++) {
arr.splice(++i,0,lib.randomInt(9));
}
const lib = { randomInt: n => Math.floor(Math.random()*n) };
(function() {
return function(string) {
var arr = string.split("")
arr.sort();
for(var i = 0; i < arr.length; i++) {
arr.splice(++i,0,lib.randomInt(9));
}
var pseudocryptarr = arr.join("");
console.log(pseudocryptarr);
}
})()("example");
Or to save an addition:
for(var i = 1; i <= arr.length; i+=2) {
arr.splice(i,0,lib.randomInt(9));
}
const lib = { randomInt: n => Math.floor(Math.random()*n) };
(function() {
return function(string) {
var arr = string.split("")
arr.sort();
for(var i = 1; i <= arr.length; i+=2) {
arr.splice(i,0,lib.randomInt(9));
}
var pseudocryptarr = arr.join("");
console.log(pseudocryptarr);
}
})()("example");
I fixed it. I wanted after each character for there to be a number. Using the pre-looped array length and doubling it while iterating twice, means that the splice adds the number after the new number element and then the character.
Edit: My typo was the problem. I didnt even have to use len, just iterate by 2.
for(var i = 0;i < arr.length;i+=2){
arr.splice((i+1),0,lib.randomInt(9));
}
(function() {
return function(string) {
var arr = string.split("")
arr.sort();
var len = arr.length
for(var i = 0;i < len*2;i+=2){
arr.splice((i+1),0,lib.randomInt(9));
}
var pseudocryptarr = arr.join("");
console.log(pseudocryptarr);
}
})()("example");
Edit: user4723924 method is better:
(function() {
return function(string) {
var arr = string.split("")
arr.sort();
for(var i = arr.length;i >= 0;i--){
arr.splice((i+1),0,lib.randomInt(9));
}
var pseudocryptarr = arr.join("");
console.log(pseudocryptarr);
}
})()("example");
Hi I am developing one jquery application. I am trying to compare the two arrays. For example,
Firstarray=["Mike","Jack"];
SecondArray=["Mike","Jack","Andy","Cruz"];
Whenever we compare above two arrays I want to return the strings which exists in both arrays or which are common to both arrays!
I tried as below. This piece of code is not working.
for (var i = 0; i < Firstarray.length; i++) {
for (var j = 0; j < SecondArray.length; j++) {
if (Firstarray[i] == SecondArray[j]) {
alert('found ' + SecondArray[j]);
return;
}
}
}
Can anyone help me in this regards! Thank you very much.
You can use indexOf() function
Firstarray=["Mike","Jack"];
SecondArray=["Mike","Jack","Andy","Cruz"];
var result = new Array();
for (var i = 0; i < Firstarray.length; i++) {
if(SecondArray.indexOf(Firstarray[i])>=0){
result.push(Firstarray[i]);
}
}
console.log(result);
Here is a solution using Array.prototype.filter and Array.prototype.some along with some ES6 flavor thrown in - see demo below:
var firstArray=["Mike","Jack"];
var secondArray=["Mike","Jack","Andy","Cruz"];
var result = secondArray.filter(a => firstArray.some(b => a === b));
console.log(result);
check this How can I find matching values in two arrays?
Array.prototype.diff = function(arr2) {
var ret = [];
this.sort();
arr2.sort();
for(var i = 0; i < this.length; i += 1) {
if(arr2.indexOf( this[i] ) > -1){
ret.push( this[i] );
}
}
return ret;
};
var FirstArray=["Mike","Jack"];
var SecondArray=["Mike","Jack","Andy","Cruz"];
var commonArray = Array();
var count=0;
for (var i=0; i<FirstArray.length; i++) {
for (var j=0;j< SecondArray.length;j++) {
if (FirstArray[i] == SecondArray[j]){
commonArray[count]=FirstArray[i];
count++;
}
}
}
console.log(commonArray);
Try changing few things in your code :
var Firstarray=["Mike","Jack"];
var SecondArray=["Mike","Jack","Andy","Cruz"];
var matchedData = [];
for (var i = 0; i < Firstarray.length; i++) {
for (var j = 0; j < SecondArray.length; j++) {
if (Firstarray[i] == SecondArray[j]) {
matchedData.push(SecondArray[j]);
}
}
}
alert(matchedData);
working fiddle :
https://jsfiddle.net/o3brcsvw/
try this
var Firstarray=["Mike","Jack"];
var SecondArray=["Mike","Jack","Andy","Cruz"];
var matchedData = [];
for (var i = 0; i < Firstarray.length; i++) {
for (var j = 0; j < SecondArray.length; j++) {
if (Firstarray[i] == SecondArray[j]) {
//alert('found ' + SecondArray[j]);
matchedData.push(SecondArray[j]);
}
}
}
return matchedData;
So that:
array = [[12,13,24],[24,22,11],[11,44,55]]
would return:
cleanedArray = [[12,13,24],[22,11],[44,55]]
I'm surprised not to have found this answered here.
var array = [[12,13,24],[24,22,11],[11,44,55]];
var output = [];
var found = {};
for (var i = 0; i < array.length; i++) {
output.push([]);
for (var j = 0; j < array[i].length; j++) {
if (!found[array[i][j]]) {
found[array[i][j]] = true;
output[i].push(array[i][j]);
}
}
}
console.log(output);
Are you looking for a function that does this for just two-dimensional arrays? If so, then I think this would work:
Array.prototype.clean = function()
{
var found = [];
for(var i = 0; i < this.length; i++)
{
for(var j = 0; j < this[i].length; j++)
{
if(found.indexOf(this[i][j]) != -1)
{
this[i].splice(j, 1);
}
else
{
found.push(this[i][j]);
}
}
}
return this;
};
If it's just a one-dimensional array you're looking for, then:
Array.prototype.clean = function()
{
var found = [];
for(var i = 0; i < this.length; i++)
{
if(found.indexOf(this[i]) != -1)
{
this.splice(i, 1);
}
else
{
found.push(this[i]);
}
}
return this;
};
this would work. If you're doing either of those, then do .clean() on your array to clean it up.
A simple function that modifies the original array is:
function removeDups(a) {
var item, j, found = {};
for (var i=0, iLen=a.length; i<iLen; i++) {
item = a[i];
j=item.length;
while (j--) {
found.hasOwnProperty(item[j])? item.splice(j,1) : found[item[j]] = '';
}
}
return a;
}