Related
For some reason, the manipulated doubleArray below is not shown in the console. Any variables that I declare after the for loop won't show to the console on both cases. Consider that in the first algorithm, there is only one for loop with x being incremented everytime. Whereas, in the second algorithm, it's a nested for loop. Can someone help me fix my error in both algorithms?
First Algorithm:
var isDuplicate = function() {
var helloWorld = [1,2,3,4,3];
var doubleValue = [];
var x = 0;
for (i = 0; i < helloWorld.length; i++) {
x = x + 1;
if (helloWorld[i] === helloWorld[x] && i !== x) {
doubleValue.push(helloWorld[i])
console.log(helloWorld[i]);
} else {
continue;
}
}
console.log(doubleValue);
};
The second Algorithm:
var isDuplicate = function() {
var helloWorld = [1,2,3,4,3];
var doubleValue = [];
for (i = 0; i < helloWorld.length; i++) {
for (x = 1; x < helloWorld.length; i++) {
if (helloWorld[i] === helloWorld[x] && i !== x) {
doubleValue.push(helloWorld[x]);
}
}
}
console.log(doubleValue);
};
In first algorithm, you are only checking if the number at current index is equal to the number at the next index, meaning you are only comparing numbers at consecutive indexes. First algorithm will work only if you have duplicate numbers on consecutive indexes.
In second algorithm, you are incrementing i in both loops, increment x in nested loop, change x = 1 to x = i + 1 and your error will be fixed.
Here's the fixed second code snippet
var isDuplicate = function() {
var helloWorld = [1,2,3,4,3, 1, 2];
var doubleValue = [];
for (let i = 0; i < helloWorld.length; i++) {
for (let x = i + 1; x < helloWorld.length; x++) {
if (helloWorld[i] === helloWorld[x] && i !== x) {
doubleValue.push(helloWorld[x]);
}
}
}
console.log(doubleValue);
};
isDuplicate();
Heres's another way to find the duplicates in an array, using an object. Loop over the array, if current number is present as key in the object, push the current number in the doubleValue array otherwise add the current number as key-value pair in the object.
const isDuplicate = function() {
const helloWorld = [1,2,3,4,3, 1, 2];
const doubleValue = [];
const obj = {};
helloWorld.forEach(n => obj[n] ? doubleValue.push(n): obj[n] = n);
console.log(doubleValue);
};
isDuplicate();
Not entirely sure what you are trying to do. If you are only looking for a method to remove duplicates you can do the following:
const hello_world = [1, 2, 2, 3, 4, 5, 5];
const duplicates_removed = Array.from(new Set(hello_world));
A set is a data object that only allows you to store unique values so, when converting an array to a set it will automatically remove all duplicate values. In the example above we are creating a set from hello_world and converting it back to an array.
If you are looking for a function that can identify all the duplicates in an array you can try the following:
const hello_world = [1, 2, 2, 3, 4, 5, 5];
const duplicates_found = hello_world.filter((item, index) => hello_world.indexOf(item) != index);
The main problem by finding duplicates is to have nested loop to compare each element of the array with any other element exept the element at the same position.
By using the second algorithm, you can iterate from the known position to reduce the iteration count.
var isDuplicate = function(array) {
var doubleValue = [];
outer: for (var i = 0; i < array.length - 1; i++) { // add label,
// declare variable i
// no need to check last element
for (var j = i + 1; j < array.length; j++) { // start from i + 1,
// increment j
if (array[i] === array[j]) { // compare values, not indices
doubleValue.push(array[i]);
continue outer; // prevent looping
}
}
}
return doubleValue;
};
console.log(isDuplicate([1, 2, 3, 4, 3])); // [3]
You could take an object for storing seen values and use a single loop for getting duplicate values.
const
getDuplicates = array => {
const
seen = {}
duplicates = [];
for (let value of array) {
if (seen[value]) duplicates.push(value);
else seen[value] = true;
}
return duplicates;
};
console.log(getDuplicates([1, 2, 3, 4, 3])); // [3]
Your first algorithm doesn't work because it only looks for duplicates next to each other. You can fix it by first sorting the array, then finding the duplicates. You can also remove the x and replace it by ++i in the loop.
var isDuplicate = function() {
var helloWorld = [1,2,3,4,3,6];
var doubleValue = [];
helloWorld = helloWorld.sort((a, b) => { return a - b });
for (i = 0; i < helloWorld.length; i++) {
if (helloWorld[i] === helloWorld[++i]) {
doubleValue.push(helloWorld[i])
console.log(helloWorld[i]);
} else {
continue;
}
}
console.log(doubleValue);
};
isDuplicate();
For the second algorithm loop, you probably meant x++ instead of i++ in the second loop. This would fix the problem.
var isDuplicate = function() {
var helloWorld = [1,2,3,4,3,4];
var doubleValue = [];
for (i = 0; i < helloWorld.length; i++) {
for (x = i + 1; x < helloWorld.length; x++) {
if (helloWorld[i] === helloWorld[x]) {
doubleValue.push(helloWorld[x]);
}
}
}
console.log(doubleValue);
};
isDuplicate()
The first algorithm can't be fixed, it can only detect consecutive duplicates,
in the second algorithm you increment i in both loops.
To avoid the duplicates beeing listed too often, you should start the second loop with i + 1
Starting with this initial 2D array:
var initialArray = [[2,3],[6,7],[4,5],[1,2],[5,6],[2,3]];
I need to create this 3D array programmatically:
var fullArray = [
[[2,3],[6,7],[4,5],[1,2],[5,6],[2,3]],
[[3,4],[0,1],[5,6],[2,3],[6,7],[3,4]],
[[4,5],[1,2],[6,7],[3,4],[0,1],[4,5]],
[[5,6],[2,3],[0,1],[4,5],[1,2],[5,6]],
[[6,7],[3,4],[1,2],[5,6],[2,3],[6,7]],
[[0,1],[4,5],[2,3],[6,7],[3,4],[0,1]],
[[1,2],[5,6],[3,4],[0,1],[4,5],[1,2]],
[[2,3],[6,7],[4,5],[1,2],[5,6],[2,3]],
[[3,4],[0,1],[5,6],[2,3],[6,7],[3,4]],
[[4,5],[1,2],[6,7],[3,4],[0,1],[4,5]],
[[5,6],[2,3],[0,1],[4,5],[1,2],[5,6]]
];
See the pattern?
On each pair, the [0] position should increment to 6 (from any starting number <= 6) and then reset to 0 and then continue incrementing. Similarly, the [1] position should increment to 7 (from any starting number <= 7) and then reset to 1 and then continue incrementing.
In this example, there are 10 2D arrays contained in the fullArray. However, I need this number to be a variable. Something like this:
var numberOf2DArraysInFullArray = 12;
Furthermore, the initial array should be flexible so that initialArray values can be rearranged like this (but with the same iteration follow-through rules stated above):
var initialArray = [[6,7],[2,3],[5,6],[4,5],[1,2],[6,7]];
Any thoughts on how to programmatically create this structure?
Stumped on how to gracefully pull this off.
Feedback greatly appreciated!
Here's a solution, I've separated the methods, and I made it so if instead of pairs it's an N size array and you want the [2] to increase up to 8 and reset to 2, if that's not needed you can simplify the of the loop for(var j = 0; j < innerArray.length; j++)
var initialArray = [[2,3],[6,7],[4,5],[1,2],[5,6],[2,3]];
var create3DArray = function(array, size){
var newArray = [initialArray];
for(var i = 0; i < size; i++)
{
newArray.push(getNextArrayRow(newArray[i]));
}
return newArray;
}
var getNextArrayRow = function(array){
var nextRow = [];
for(var i = 0; i < array.length; i++)
{
var innerArray = array[i];
var nextElement = [];
for(var j = 0; j < innerArray.length; j++)
{
var value = (innerArray[j] + 1) % (7 + j);
value = value === 0 ? j : value;
nextElement.push(value);
}
nextRow.push(nextElement);
}
return nextRow;
}
console.log(create3DArray(initialArray,3));
Note, the results from running the snippet are a bit difficult to read...
var initialArray = [[2,3],[6,7],[4,5],[1,2],[5,6],[2,3]];
var numOfArrays = 10;
// get a range array [0, 1, 2, ...]
var range = [];
for (var i = 0; i < numOfArrays; i++) {
range.push(i);
}
var result = range.reduce(function(prev, index) {
if (index == 0) {
return prev;
}
prev.push(transformArray(prev[index - 1]));
return prev;
}, [initialArray])
console.log(result);
function transformArray(arr) {
return arr.map(transformSubArray)
}
function transformSubArray(arr) {
return arr.map(function(val) {
return val == 7 ? 0 : val + 1;
})
}
Here's a pretty simple functional-ish implementation
I have two arrays
var arr1 = ['wq','qw','qq'];
var arr2 = ['wq','wq','wq','qw','qw','qw','qw','qq','qq'];
Below what i did is matching arr1 values with arr2. If the array contains same values i pushed the values into newArr.
var newArr = [];
for (var i=0;i<arr1.length;i++) {
newArr[i] = [];
}
for (var i=0;i<arr2.length;i++) {
for (var j=0;j<arr1.length;j++) {
if (arr2[i].indexOf(arr1[j]) != -1)
newArr[j].push(arr2[i]);
}
}
console.log(newArr[1]); //newArr[0] = ['wq','wq','wq'];//In second output array newArr[1] = ['qw','qw','qw','qw'];
Is there any easy way to solve this without using two for loops. Better i need a solution in javascript
Maybe use indexOf():
var count = 0;
for (var i = 0; i < arr1.length; i++) {
if (arr2.indexOf(arr1[i]) != -1) {
count++;
// if you just need a value to be present in both arrays to add it
// to the new array, then you can do it here
// arr1[i] will be in both arrays if you enter this if clause
}
}
if (count == arr1.length) {
// all array 1 values are present in array 2
} else {
// some or all values of array 1 are not present in array 2
}
Your own way wasn't totally wrong, you just had to check if the element was index of the array and not of an element in the array.
var arr1 = ['wq','qw','qq'];
var arr2 = ['wq','wq','wq','qw','qw','qw','qw','qq','qq'];
var newArr = [];
for (var i in arr1) {
newArr[i] = [];
}
for (var i in arr2) {
var j = arr1.indexOf(arr2[i]);
if (j != -1) {
newArr[j].push(arr2[i]);
}
}
This way you removed the nested for loop and it still gives you the result you asked for.
var arr1 = ['wq','qw','qq','pppp'];
var arr2 = ['wq','wq','wq','qw','qw','qw','qw','qq','qq'];
function intersect(a, b) {
var d = {};
var results = [];
for (var i = 0; i
d[b[i]] = true;
}
for (var j = 0; j
if (d[a[j]])
results.push(a[j]);
}
return results;
}
var result_array = intersect(arr1,arr2);
// result_array will be like you want ['wq','wq','wq'];
Hey i have a simple question i cant find an answer,
i´m trying to generate some raw-data for a chart
lets say i have an array like :
[1,0,0,1,2,0]
is there a way to make an array out of it that has nested arrays that represent the count of duplicate entrys ?
[[0,3],[1,2],[2,1]]
here is some code that does the trick, but saves the count as objects
var array = [1,0,0,1,2,0];
var length = array.length;
var objectCounter = {};
for (i = 0; i < length; i++) {
var currentMemboerOfArrayKey = JSON.stringify(array[i]);
var currentMemboerOfArrayValue = array[i];
if (objectCounter[currentMemboerOfArrayKey] === undefined){
objectCounter[currentMemboerOfArrayKey] = 1;
}else{
objectCounter[currentMemboerOfArrayKey]++;
}
}
but objectCounter returns them like
{0:3,1:2,2:1}
but i need it as an array i specified above ?
for any help, thanks in advance
Try
var array = [1, 0, 0, 1, 2, 0];
function counter(array) {
var counter = [],
map = {}, length = array.length;
$.each(array, function (i, val) {
var arr = map[val];
if (!arr) {
map[val] = arr = [val, 0];
counter.push(arr);
}
arr[1] += 1;
})
return counter;
}
console.log(JSON.stringify(counter(array)))
Demo: Fiddle
You can turn your object into an array easily:
var obj = {0:3,1:2,2:1};
var arr = [];
for (var key in obj) {
// optional check against Object.prototype changes
if (obj.hasOwnProperty(key)) {
arr.push([+key, obj[key]]);
}
}
Note: The object keys are strings, so i converted them back to numbers when placed in the array.
Functional way of doing this, with Array.reduce and Array.map
var data = [1,0,0,1,2,0];
var result = data.reduce(function(counts, current) {
counts[current] = current in counts ? counts[current] + 1: 1;
return counts;
}, {});
result = Object.keys(result).map(function(current){
return [parseInt(current), result[current]];
});
console.log(result);
Output
[ [ 0, 3 ], [ 1, 2 ], [ 2, 1 ] ]
Try:
var data = [1,0,0,1,2,0];
var len = data.length;
var ndata = [];
for(var i=0;i<len;i++){
var count = 0;
for(var j=i+1;j<len;j++){
if(data[i] == data[i]){
count ++;
}
}
var a = [];
a.push(data[i]);
a.push(count);
ndata.push(a);
}
console.log(ndata)
DEMO here.
First you need to map the array to an associative object
var arr = [1,0,0,1,2,0];
var obj = {};
for (var i = 0; i < arr.length; i++) {
if (obj[arr[i]] == undefined) {
obj[arr[i]] = 0;
}
obj[arr[i]] += 1;
}
Then you can easily turn that object into a 2d matrix like so:
arr = [];
for (var k in obj) {
arr.push([k, obj[k]]);
}
alert(JSON.stringify(arr));
Your existing object can be turned into an array with a simple for..in loop. Also your existing code that produces that object can be simplified. Encapsulate both parts in a function and you get something like this:
function countArrayValues(array) {
var counter = {},
result = [];
for (var i = 0, len = array.length; i < len; i++)
if (array[i] in counter)
counter[array[i]]++;
else
counter[array[i]] = 1;
for (i in counter)
result.push([+i, counter[i]]);
return result;
}
console.log( countArrayValues([1,0,0,1,2,0]) );
Demo: http://jsfiddle.net/hxRz2/
I need to find a missing array in an "array of arrays". I started by finding this function below (on StackOverflow):
function findDeselectedItem(CurrentArray, PreviousArray) {
var CurrentArrSize = CurrentArray.length;
var PreviousArrSize = PreviousArray.length;
var deselectedItem = [];
// loop through previous array
for(var j = 0; j < PreviousArrSize; j++) {
// look for same thing in new array
if (CurrentArray.indexOf(PreviousArray[j]) == -1)
deselectedItem.push(PreviousArray[j]);
}
return deselectedItem;
}
This works just fine if you did something like this:
oldarray = ["hi", "ho", "hey"];
newarray = ["hi", "hey"];
Using findDeselectedItem(newarray, oldarray) would return ["ho"].
However, my content looks like this:
oldarray = [["James", 17, 1], ["Olivia", 16, 0], ["Liam", 18, 1]];
newarray = [["Olivia", 16, 0], ["James", 17, 1]];
How can I adapt the function above so that it returns the missing array containing 'Liam'.
Thanks
I would make a hash with the name as a key. That would make finding missing content trivial and very fast. You can then optimize the method by not rebuilding the hash every time, but only when it's really necessary.
var oldArray = [["James", 17, 1], ["Olivia", 16, 0], ["Liam", 18, 1]];
var newArray = [["Olivia", 16, 0], ["James", 17, 1]];
function findDeselectedItems(oldArray, newArray)
{
var results = [];
var hash = {};
for (var i=0; i<newArray.length; i++) {
hash[newArray[i].join(',')] = true;
}
for (var i=0; i<oldArray.length; i++) {
if (!hash[oldArray[i].join(',')]) {
results.push(oldArray[i]);
}
}
return results;
}
The problem may be that indexOf uses strict equality. I.e. if an item in the 'previous' array isn't literally also in the 'current' array, it will report it to not be in there.
You will have to iterate over the values yourself (instead of using indexOf) and check if the array contains something that is 'the same as' (but not literally the same) the array.
I.e. if I didn't explain myself well enough take a look at this;
['bob'] == ['bob']; //false
//therefore
[['bob']].indexOf(['bob']); //-1
I hope that this helps you,
function findDeselectedItem(CurrentArray, PreviousArray) {
var CurrentArrSize = CurrentArray.length;
var PreviousArrSize = PreviousArray.length;
var deselectedItem = [];
// loop through previous array
for(var j = 0; j < PreviousArrSize; j++) {
var checkArray = PreviousArrSize[j];
// loop through 2nd array to match both array
for(var i = 0; i < CurrentArrSize; i++) {
// look for same thing in new array
if (CurrentArray[i].indexOf(checkArray) == -1)
deselectedItem.push(CurrentArray[i]);
}
}
return deselectedItem;
}
#KarelG: nice and quick solution but should it not be var checkArray = PreviousArr[j]; instead of var checkArray = PreviousArrSize[j]; ?
function findDeselectedItem(CurrentArray, PreviousArray) {
var CurrentArrSize = CurrentArray.length;
var PreviousArrSize = PreviousArray.length;
var deselectedItem = [];
var selectedIndices = [];
// loop through previous array
for(var j = 0; j < PreviousArrSize; j++) {
for(k=0; k < CurrentArrSize ; k++){
if (CurrentArray[k].toString() === PreviousArray[j].toString()){
selectedIndices.push(j);
break;
}
}
}
for(var l = 0; l < PreviousArrSize; l++){
if(selectedIndices.indexOf(l) === -1){
deselectedItem.push(PreviousArray[l]);
}
}
return deselectedItem;
}
I don't think you can use indexOf to compare two arrays. You need a deeper comparison. Although this code could be written another way, you could do this with an array comparison function and using Array.some() to filter through your elements. Here's an example and a fiddle;
// Credit http://stackoverflow.com/questions/7837456/comparing-two-arrays-in-javascript
// attach the .compare method to Array's prototype to call it on any array
Array.prototype.compare = function (array) {
// if the other array is a falsy value, return
if (!array)
return false;
// compare lengths - can save a lot of time
if (this.length != array.length)
return false;
for (var i = 0; i < this.length; i++) {
// Check if we have nested arrays
if (this[i] instanceof Array && array[i] instanceof Array) {
// recurse into the nested arrays
if (!this[i].compare(array[i]))
return false;
}
else if (this[i] != array[i]) {
// Warning - two different object instances will never be equal: {x:20} != {x:20}
return false;
}
}
return true;
}
function findDeselectedItem(CurrentArray, PreviousArray) {
var CurrentArrSize = CurrentArray.length;
var PreviousArrSize = PreviousArray.length;
var deselectedItem = [];
// loop through previous array
for (var j = 0; j < PreviousArrSize; j++) {
// look for same thing in new array
CurrentArray.some(function (a, idx) {
if(PreviousArray[j].compare(a) == false) {
deselectedItem.push(PreviousArray[j]);
return true;
}
});
}
return deselectedItem;
}
var oldarray =[["James", 17, 1], ["Olivia", 16, 0], ["Liam", 18, 1]];
var newarray =[["Olivia", 16, 0], ["James", 17, 1]];
console.log(findDeselectedItem(newarray, oldarray));