variable i'm not splicing is being spliced - javascript

I am trying to make a function that takes in an array, and prints versions of the array with one number missing. For example, if the array were [1,2,3], it would print [2,3],[1,3], [1,2]. So I'm making a variable tempSeq, setting it equal to Sequence, printing it with Document.write(), and then resetting tempSeq to the original sequence. For some reason however, the variable sequence is being spliced. Not sure why this is happening, and any help would be appreciated!
function almostIncreasingSequence(sequence) {
var tempseq = sequence;
for (let i = 0; i < sequence.length; i++) {
tempseq = sequence;
tempseq.splice(i, 1);
document.write("(" + tempseq + ")");
}
return tempseq;
}
almostIncreasingSequence([10, 1, 2, 3, 4, 5]);
The function name is odd because ultimately the function is doing something else.

This line is actually saying 'call the "sequence" array also "tempseq"'
var tempseq = sequence;
and it is not saying 'clone the "sequence" array into "tempseq" (if you expect this behavior). Then splice actually operating on sequence array
tempseq.splice(i, 1); // equal to sequence.splice(i, 1)
Just clone the array:
// instead of
// var tempseq = sequence;
var tempseq = sequence.slice();
function almostIncreasingSequence(sequence) {
var tempseq = sequence.slice();
for (let i = 0; i < sequence.length; i++) {
tempseq = sequence;
tempseq.splice(i, 1);
document.write("(" + tempseq + ")");
}
return tempseq;
}
almostIncreasingSequence([10, 1, 2, 3, 4, 5]);

When you assign tempseq = sequence tempseq is still the same array, it is just a reference so splice effects both. Use reduce to create a copy of the array without the item at i
function almostIncreasingSequence(sequence) {
var tempseq = sequence;
for (let i = 0; i < sequence.length; i++) {
const tempseq = sequence.reduce((results, item, index) => index === i ? results : [...results, item], []);
document.write("(" + tempseq + ")");
}
return tempseq;
}
almostIncreasingSequence([10, 1, 2, 3, 4, 5]);

Related

How to get unique sub arrays within an array in Javascript

So I have this function that determines whether 2 the sum of two numbers within an array are equal to a given target number.
The function gives out all the possible combinations of achieving the target number but I only want unique sub-arrays.
let targetNum = 10
const array = [5,2,3,3,7,1,5]
const sumTwoNums = (array,num) => {
let newArray = [];
for (var i=0;i<array.length;i++) {
for (var j=0;j<array.length;j++) {
if(i!==j && array[i]+array[j]===num){
newArray.push([array[i],array[j]]);
}
}
}
return newArray
}// returns [[5,5],[3,7],[3,7],[7,3],[7,3],[5,5]]
What can I do to solve this issue?
I think this answer solves your problem .
function allPairs(ints, s) {
var hash = Object.create(null),
i,
value,
pairs = [];
for (i = 0; i < ints.length; i++) {
value = ints[i];
if (hash[value]) pairs.push([s - value, value]);
hash[s - value] = true;
}
return pairs;
}
console.log(allPairs([7, 2, 5, 8, 4, 3], 7));

Removing identical items in an array

Beginner programmer here. I'm struggling with an assignment that's taking input text, splitting the words into single array items and then listing the total number of each words in an output. The splitting of the input works fine, but I need to check the array for duplicate items and remove that item (need to keep it unique) while also increasing the count on that particular word.
The idea was to make an array consisting of the words alone, and another that keeps track of the count. Glad to receive tips to use a simpler approach as well.
And yes, I know there is several solutions to this problem on SO, but I dont quite understand how to fix this particular code using functions.
function gen()
{
var arr = [];
var counter = [];
var str = document.getElementById("inpTxt").value;
str.toString();
str = str.split(" ");
for(var i = 0; i < str.length; i++)
{
arr.push(str[i]);
counter[i]++; //ignore that this array hasnt been properly declared yet, Im trying to make this equal length of arr with default value 0
//tried nested loop here for making comparison, didnt work
document.getElementById("print").innerHTML += "Total number of the word \"" + arr[i] + "\": " + counter[i] + " <br />";
}
}
If you're using ECMAScript2015(ES6), you can build a Set - which guarantees unicity - from your array :
var inputArray = [1, 1, 2, 3, 2, 4, 5, 5, 4, 1];
console.log(new Set(inputArray)) // displays Set { 1, 2, 3, 4, 5 }
Otherwise, you can loop over the array and check if a particular element follows another occurrence of itself :
var inputArray = [1, 1, 2, 3, 2, 4, 5, 5, 4, 1];
// with ES6 :
var result = inputArray.filter((element, index) => ! inputArray.slice(0, index).includes(element));
// without ES6 :
result=[];
for (var i=0; i<inputArray.length; i++) {
var currentElement = inputArray[i];
var previouslyFound = false;
for (var j=0; j<i && !previouslyFound; j++) {
previouslyFound = inputArray[i] == inputArray[j];
}
if (!previouslyFound) result.push(currentElement);
}
However, since we are looping over the array, it would be as fast to count the occurrences without unicizing the array first :
var inputArray = [1, 1, 2, 3, 2, 4, 5, 5, 4, 1];
// with ES6 :
var result = inputArray.reduce(function(map, element) {
map[element] = map.hasOwnProperty(element) ? map[element] + 1 : 1;
return map;
}, {});
// without ES6 :
var result = {};
for (var i=0; i<inputArray.length; i++) {
var currentElement = inputArray[i];
if (result.hasOwnProperty(currentElement)) {
result[currentElement] = result[currentElement] + 1;
} else {
result[currentElement] = 1;
}
}
Try the indexOf method of arrays to figure out whether you already have the string in array.
function gen()
{
var arr = [];
var counter = [];
var str = document.getElementById("inpTxt").value;
str.toString();
str = str.split(" ");
for(var i=0; i < str.length; i++)
{
if(arr.indexOf(str)==-1){
arr.push(str[i]);
counter[i]++; //ignore that this array hasnt been properly declared yet, Im trying to make this equal length of arr with default value 0
}
//tried nested loop here for making comparison, didnt work
document.getElementById("print").innerHTML += "Total number of the word \"" + arr[i] + "\": " + counter[i] + " <br />";
}
}
PS: please know that there are less expensive methods available out there but i am just trying to help with whatever i can.

javascript function that takes array as input, increases each array element by 1 and returns new array with increased values not working

I'm totally new to javascript. I'm learning how to write functions for the first time and I'm stuck with this one. Please can you help me figure out why my for loop is only looping on the first element of the array and not the others.
Thank you for your help.
See code:
I'm trying to write a function that takes as input an array of numbers and returns a new array that contains each number from the input array, increased by one.
function incrementEach (myArray) {
var newArray = [];
for (var i = 0; i < myArray.length; i++) {
newArray.push(myArray + 1);
return newArray;
};
};
var nuArray = incrementEach ([23, 34, 56, 67]);
log (nuArray);
The result I get after running this code is: '[24]'
Only the first element in the array is increased and printed. Something must be wrong with my loop but I can't figure it out. Please help me!
Your code has a couple of problems:
In your newArray.push call, you're pushing the entire array + 1 instead of the individual item + 1.
You're returning within your loop, which means it is not a loop at all and only gets run once.
Here is your code with fixes in place:
function incrementEach (myArray) {
var newArray = [];
for (var i = 0; i < myArray.length; i++) {
newArray.push(myArray[i] + 1);
};
return newArray;
};
var nuArray = incrementEach ([23, 34, 56, 67]);
log(nuArray);
You could also use the map function to do this with much less code:
var nuArray = [23, 34, 56, 67].map(function(item) {
return item + 1;
});
You need to grab the element from the array:
newArray.push(myArray[i] + 1);
You probably want
function incrementEach (myArray) {
var newArray = [];
for (var i = 0; i < myArray.length; ++i) {
newArray.push(myArray[i] + 1); // i-th element
}
return newArray; // Return at the end
}
However, it would be simpler like this:
[23, 34, 56, 67].map(n => n+1);
var arr
function incrementEach (myArray) {
for (var i = 0; i < myArray.length; i++) {
myArray[i] += 1
};
return myArray
};
arr = incrementEach([23, 34, 56, 67]);
log(arr);
Best use case for .map(). Which creates a new array with the results of calling a provided function on every element in this array.
var increased = [1, 2, 3].map(function(item, index) {
return item + 1;
});
A function could look like:
function increaseValues(arr, amount) {
return arr.map(function(item) {
return item + amount;
});
}
// increase array values by 5
increaseValues([1,2,4], 5);
You are accessing the array itself not the item being looped.
use newArray.push(myArray[i] + 1); instead of newArray.push(myArray + 1); inside the loop
Also, the return statement should be outside the for loop
DEMO

Remove Duplicate rows in multidimensional array using Javascript

var MyArray = [
[1, "07/28/2014"],
[2, "07/29/2014"],
[3, "07/28/2014"],
[4, "07/30/2014"],
[5, "07/28/2014"],
];
In this array, how to remove the duplicate columns and find count the removed items.
I need individual count for removed items.
like
07/28/2014 is 2 times.
This is my Code:
function(MyArray, search_val)
{
var counter = 0; alert(MyArray.length);
for(var i = 0; i < MyArray.length; i++)
{
if(MyArray[i][0] == search_val)
{
MyArray.splice(i, 1);
counter++;
}
}
alert("counter: "+counter);
return counter;
}
Here are a couple very naive basic solutions. Both of these examples are for demonstration purposes only. Do not use in production code. There are parameter validation and other checks that were left out to simplify the examples. Further, depending on your browser requirements, or available frameworks, there are much faster and better ways to do your equality tests. Think of this as a starting point for more research.
I'll leave it as an exercise to improve these answers.
For your data exclusively, this would work:
var count, isFirst, data = [[1,"07/28/2014"], [2,"07/29/2014"],[3, "07/28/2014"],[1,"07/28/2014"],[4, "07/30/2014"]];
count = 0
/* loop over each element of the array */
for(var x = 0; x < data.length; x++) {
isFirst = true // used to skip the first matching element
/* for each loop iteration, loop over every element in the array */
for(var y = 0; y < data.length; y++) {
/*
check the inner loop element against the outer loop element
to see if they satisfy your equality requirements.
Notice the second set of index operator brackets, this is
how you access the next dimension of the array.
*/
if(data[x][1] === data[y][1]) {
/*
If this is not the first time we've found this match
then this must be a duplicate element, so remove it
*/
if (!isFirst) {
data.splice(y, 1);
count++;
}
isFirst = false // makes sure that future matches are removed
}
}
}
console.log(count);
console.log(data);
For a more general solution one possibility would be to pass in the equality test as an anonymous function:
/* Note, this is the same algorithm as above */
function spliceIf(data, predicate) {
var count = 0, isFirst;
for(var x = 0; x < data.length; x++) {
isFirst = true;
for(var y = 0; y < data.length; y++) {
if (predicate(data[x], data[y])) {
if (!isFirst) {
data.splice(y, 1);
count++;
}
isFirst = false
}
}
}
return count;
}
var items = [[1,"07/28/2014"], [2,"07/29/2014"],[3, "07/28/2014"],[1,"07/28/2014"],[4, "07/30/2014"]];
// Now call the new function and pass in the equality test as the second parameter:
var itemsRemoved = spliceIf(items,
function(a, b) {
/*
This predicate function will be passed to spliceIf. When it
is called from within then spliceIf function, it will be
provided with the inner and outer elements of the loop.
You can then do your equality test however you see fit.
Notice the predicate function must return a value.
This is equivalent to the "data[x][1] === data[y][1]" line
in the example above.
*/
return a[1] === b[1];
}
);
console.log(itemsRemoved);
console.log(items);
Just doing some fiddles, I thought this might help. JSFiddle of Duplicate Remover Function
var data = [
[1, "07/28/2014"],
[2, "07/29/2014"],
[3, "07/28/2014"],
[4, "07/30/2014"],
[5, "07/28/2014"],
];
var data2 = [
[1, "07/28/2014"],
[2, "07/29/2014"],
[3, "07/29/2014"],
[4, "07/29/2014"],
[5, "07/29/2014"],
];
function removeDuplicates(Array){
this._newArray = [];
this.numberOfDuplicates = 0;
this.listDuplicates = [];
//Remove Duplicates
for(i=0;i<Array.length;i++){
for(j=0;j<Array.length;j++){
if(!Array[i][1]) //skip the current loop if index is empty
break;
if(Array[i][1]==Array[j][1] && i!=j){
this.listDuplicates.push(Array[j]);
Array[j]=0;
this.numberOfDuplicates+=1; //increase counter for dupes
}
}
}
//Recreate Array
this.newArray = function(){
for(i=0;i<Array.length;i++){
if(Array[i])
this._newArray.push(Array[i]);
}
return this._newArray;
}
}
var data = new removeDuplicates(data);
console.log(data.newArray());
console.log(data.numberOfDuplicates + " Duplicates");
console.log(data.listDuplicates);
console.log("\n");
var data2 = new removeDuplicates(data2);
console.log(data2.newArray());
console.log(data2.numberOfDuplicates + " Duplicates");
console.log(data2.listDuplicates);

Remove array of indexes from array

John Resig, creator of jQuery created a very handy Array.remove method that I always use it in my projects:
// Array Remove - By John Resig (MIT Licensed)
Array.prototype.remove = function(from, to) {
var rest = this.slice((to || from) + 1 || this.length);
this.length = from < 0 ? this.length + from : from;
return this.push.apply(this, rest);
};
// Remove the second item from the array
array.remove(1);
// Remove the second-to-last item from the array
array.remove(-2);
// Remove the second and third items from the array
array.remove(1,2);
// Remove the last and second-to-last items from the array
array.remove(-2,-1);
It works great. But I would like to know if it's extendable so that it can take an array of indexes as the first argument?
Otherwise, I will probably make another method that makes use of it:
if (!Array.prototype.removeIndexes) {
Array.prototype.removeIndexes = function (indexes) {
var arr = this;
if (!jQuery)
throw new ReferenceError('jQuery not loaded');
$.each(indexes, function (k, v) {
var index = $.inArray(v, indexes);
if (index !== -1)
arr.remove(index);
});
};
}
If Array.remove() isn't extendable to fit my needs, what do you think about my other solution above?
I think this is what you are looking for (It works with negative index too) :
if (!Array.prototype.removeIndexes) {
Array.prototype.removeIndexes = function (indexes) {
var arr = this;
if (!jQuery) throw new ReferenceError('jQuery not loaded');
var offset = 0;
for (var i = 0; i < indexes.length - 1; i++) {
if (indexes[i] < 0)
indexes[i] = arr.length + indexes[i];
if (indexes[i] < 0 || indexes[i] >= arr.length)
throw new Error('Index out of range');
}
indexes = indexes.sort();
for (var i = 0; i < indexes.length - 1; i++) {
if (indexes[i + 1] == indexes[i])
throw new Error('Duplicated indexes');
}
$.each(indexes, function (k, index) {
arr.splice(index - offset, 1);
offset++;
});
return arr;
};
}
var a = ['a', 'b', 'c', 'd', 'e', 'f'];
var ind = [3, 2, 4];
a.removeIndexes(ind);
console.log(a.join(', '));
// returns : a, b, f
See fiddle
This version should work. It modifies the original array. If you prefer to return a new array without modifying the original, use the commented out initializer of result and add return result at the end of the function.
Array.prototype.removeIndexes = function(indices) {
// make sure to remove the largest index first
indices = indices.sort(function(l, r) { return r - l; });
// copy the original so it is not changed
// var result = Array.prototype.slice.call(this);
// modify the original array
var result = this;
$.each(indices, function(k, ix) {
result.splice(ix, 1);
});
}
> [0, 1, 2, 3, 4, 5, 6, 7, 8].removeIndexes([4, 5, 1]);
> [0, 2, 3, 6, 7, 8]
How about
Array.prototype.remove = function (indexes) {
if(indexes.prototype.constructor.name == "Array") {
// your code to support indexes
} else {
// the regular code to remove single or multiple indexes
}
};

Categories

Resources