Return numbers which appear only once (JavaScript) - javascript

Say I have the array [1,2,3,5,2,1,4]. How do I get make JS return [3,4,5]?
I've looked at other questions here but they're all about delete the copies of a number which appears more than once, not both the original and the copies.
Thanks!

Use Array#filter method twice.
var data = [1, 2, 3, 5, 2, 1, 4];
// iterate over elements and filter
var res = data.filter(function(v) {
// get the count of the current element in array
// and filter based on the count
return data.filter(function(v1) {
// compare with current element
return v1 == v;
// check length
}).length == 1;
});
console.log(res);
Or another way using Array#indexOf and Array#lastIndexOf methods.
var data = [1, 2, 3, 5, 2, 1, 4];
// iterate over the array element and filter out
var res = data.filter(function(v) {
// filter out only elements where both last
// index and first index are the same.
return data.indexOf(v) == data.lastIndexOf(v);
});
console.log(res);

You can also use .slice().sort()
var x = [1,2,3,5,2,1,4];
var y = x.slice().sort(); // the value of Y is sorted value X
var newArr = []; // define new Array
for(var i = 0; i<y.length; i++){ // Loop through array y
if(y[i] != y[i+1]){ //check if value is single
newArr.push(y[i]); // then push it to new Array
}else{
i++; // else skip to next value which is same as y[i]
}
}
console.log(newArr);
If you check newArr it has value of:
[3, 4, 5]

var arr = [1,2,3,5,2,1,4]
var sorted_arr = arr.slice().sort(); // You can define the comparing function here.
var nonduplicates = [];
var duplicates=[];
for (var i = 0; i < arr.length; i++) {
if (sorted_arr[i + 1] == sorted_arr[i]) {
duplicates.push(sorted_arr[i]);
}else{
if(!duplicates.includes(sorted_arr[i])){
nonduplicates.push(sorted_arr[i]);
}
}
}
alert("Non duplicate elements >>"+ nonduplicates);
alert("Duplicate elements >>"+duplicates);

I think there could exists option with Map.
function unique(array) {
// code goes here
const myMap = new Map();
for (const el of array) {
// save elements of array that came only once in the same order
!myMap.has(el) ? myMap.set(el, 1) : myMap.delete(el);
}
return [...myMap.keys()];
}
const array = [1,2,3,5,2,1,4];
//[11, 23, 321, 300, 50, 23, 100,89,300];
console.log(unique(array));

Related

find intersection elements in arrays in an array

I need to construct a function intersection that compares input arrays and returns a new array with elements found in all of the inputs.
The following solution works if in each array the numbers only repeat once, otherwise it breaks. Also, I don't know how to simplify and not use messy for loops:
function intersection(arrayOfArrays) {
let joinedArray = [];
let reducedArray = [];
for (let iOuter in arrayOfArrays) {
for (let iInner in arrayOfArrays[iOuter]) {
joinedArray.push(arrayOfArrays[iOuter][iInner]);
}
return joinedArray;
}
for (let i in joinedArray.sort()) {
if (joinedArray[i] === joinedArray[ i - (arrayOfArrays.length - 1)]) {
reducedArray.push(joinedArray[i]);
}
}
return reducedArray;
}
Try thhis:-
function a1(ar,ar1){
x = new Set(ar)
y = new Set(ar1)
var result = []
for (let i of x){
if (y.has(i)){
result.push(i)
}
}
if (result){return result}
else{ return 0}
}
var a= [3,4,5,6]
var b = [8,5,6,1]
console.log(a1(a,b)) //output=> [5,6]
Hopefully this snippet will be useful
var a = [2, 3, 9];
var b = [2, 8, 9, 4, 1];
var c = [3, 4, 5, 1, 2, 1, 9];
var d = [1, 2]
function intersect() {
// create an empty array to store any input array,All the comparasion
// will be done against this one
var initialArray = [];
// Convert all the arguments object to array
// there can be n number of supplied input array
// sorting the array by it's length. the shortest array
//will have at least all the elements
var x = Array.prototype.slice.call(arguments).sort(function(a, b) {
return a.length - b.length
});
initialArray = x[0];
// loop over remaining array
for (var i = 1; i < x.length; i++) {
var tempArray = x[i];
// now check if every element of the initial array is present
// in rest of the arrays
initialArray.forEach(function(item, index) {
// if there is some element which is present in intial arrat but not in current array
// remove that eleemnt.
//because intersection requires element to present in all arrays
if (x[i].indexOf(item) === -1) {
initialArray.splice(index, 1)
}
})
}
return initialArray;
}
console.log(intersect(a, b, c, d))
There is a nice way of doing it using reduce to intersect through your array of arrays and then filter to make remaining values unique.
function intersection(arrayOfArrays) {
return arrayOfArrays
.reduce((acc,array,index) => { // Intersect arrays
if (index === 0)
return array;
return array.filter((value) => acc.includes(value));
}, [])
.filter((value, index, self) => self.indexOf(value) === index) // Make values unique
;
}
You can iterate through each array and count the frequency of occurrence of the number in an object where the key is the number in the array and its property being the array of occurrence in an array. Using the generated object find out the lowest frequency of each number and check if its value is more than zero and add that number to the result.
function intersection(arrayOfArrays) {
const frequency = arrayOfArrays.reduce((r, a, i) => {
a.forEach(v => {
if(!(v in r))
r[v] = Array.from({length:arrayOfArrays.length}).fill(0);
r[v][i] = r[v][i] + 1;
});
return r;
}, {});
return Object.keys(frequency).reduce((r,k) => {
const minCount = Math.min(...frequency[k]);
if(minCount) {
r = r.concat(Array.from({length: minCount}).fill(+k));
}
return r;
}, []);
}
console.log(intersection([[2,3, 45, 45, 5],[4,5,45, 45, 45, 6,7], [3, 7, 5,45, 45, 45, 45,7]]))

Comparing an array to an array set in JavaScript

I want to compare an array with an array set.
For example,
array 1 = [[1,2,3],[1,4,5]];
array 2 = [1,3,6,5,4];
Since the elements 1,4,5 in array 2 match with a set in array 1 it should return true.
use loop and loop. get all child array in array1, and check each child array include in array2.
function check(){
var array1 = [[1,2,3],[1,4,5]];
var array2 = [1,3,6,5,4];
for(let arr of array1){
let flag=true;
for(let child of arr){
if(array2.indexOf(child) < 0){
flag = false;
break; // if one element not in array2, enter next loop.
}
}
if(flag) return flag; // if got one child array elements all in array2, stop loop.
}
}
Iterate over your array and check if the value exists in the other array.
var sets = [
[1, 2, 3],
[1, 4, 5]
],
valid = [1, 3, 6, 5, 4];
var processed = sets.map(set => set.every(val => valid.includes(val)));
console.log( processed);
There are ways to make this more efficient, but try this for starters.
Here's an example how you can check if any are true:
// Check if any are true
var any = processed.some(v=>v);
console.log( any );
You can iterate over array1 and use every() on each number group and as a condition for it use includes() with the second array for a relatively short syntax:
var array1 = [
[1, 2, 3],
[1, 4, 5]
];
var array2 = [1, 3, 6, 5, 4];
var results = [];
array1.forEach(function(item, index, array) {
if (item.every(x => array2.includes(x))) {
results.push(item)
}
});
console.log(results)
Edited : I'm pushing the results that return true to an empty array ...
Flatten the first array (unpack the nested arrays). Then do an intersection of the flattened array and the second array. Map through the first array, and for each each array do an intersection against the second array. Then filter out all arrays that are empty. If the resulting array contains something, then something matched.
const hasMatch = Boolean(array1.map(a => intersect(a, array2)).filter(i => i.length).length)
var array1 = [
[1, 2, 3],
[1, 4, 5]
];
var array2 = [1, 3, 6, 5, 4];
var isMatch = doesNestedArrayMatchArray(array1, array2);
function doesNestedArrayMatchArray(nestedArray, bigArray) {
var atLeastOneMatch = false;
for (var i = 0; i < nestedArray.length; i++) {
var innerMatch = true;
//go through each array of array1
for (var j = 0; j < nestedArray[i].length; j++) {
if (bigArray.indexOf(nestedArray[i][j]) == -1){
innerMatch = false;
break;
}
}
if (innerMatch) atLeastOneMatch = true;
}
return atLeastOneMatch;
}
console.log(isMatch)

Javascript function. What is missing?

Write a program to find count of the most frequent item of an array. Assume that input is array of integers.
Example:
Input array: [3, -1, -1, -1, 2, 3, -1, 3, -1, 2, 4, 9, 3]
Ouptut: 5
Most frequent number in example array is -1. It occurs 5 times in input array.
Here is my code:
function mostFrequentItemCount(collection) {
var copy = collection.slice(0);
for (var i = 0; i < collection.length; i++) {
var output = 0;
for (var x = 0; x < copy.length; x++) {
if (collection[i] == copy[x]) {
output++;
}
}
}
return output;
}
It seems to be just counting the reoccurrence of the first number in the array not the one that occurs the most. I can't figure out how to make it count the most occurring one.
If i didn't miss anything, and if you really want to find the count of the most frequent item of an array, i guess one approach would be this one:
function existsInCollection(item, collection) {
for(var i = 0; i < collection.length; i++) {
if(collection[i] === item) {
return true;
}
}
return false;
}
function mostFrequentItemCount(collection) {
var most_frequent_count = 0;
var item_count = 0;
var already_checked = [];
for(var i = 0; i < collection.length; i++) {
// if the item was already checked, passes to the next
if(existsInCollection(collection[i], already_checked)) {
continue;
} else {
// if it doesn't, adds to the already_checked list
already_checked.push(collection[i]);
}
for(var j = 0; j < collection.length; j++)
if(collection[j] === collection[i])
item_count++;
if(item_count > most_frequent_count)
most_frequent_count = item_count;
item_count = 0;
}
return most_frequent_count;
}
var items = [3, -1, -1, -1, 2, 3, -1, 3, -1, 2, 4, 9, 3];
alert(mostFrequentItemCount(items));
What happens here is:
On each item ('i' loop), it will run another loop ('j') through all items, and count how many are equal to the [i] item. After this second loop, it will be verified if that item count is greater than the most_frequent_count that we already have, and if it is, updates it.
Since we always use the same variable 'item_count' to check each number count, after the verification of each number we reset it to 0.
This may not be the best answer, but it was what occurred me at the moment.
EDIT:
I added a function to check if an item already exists in a list, to avoid the loop from check the same item again.
The problem is that you override the output variable each loop iteration, so after the for loop ends your output variable holds occurrences of the last element of input array.
You should use variables like var best_element = collection[0] and var best_element_count = -1 (initialized like this). After each inner loop you check if algo found any better solution (best_element_count < output) and update best_element.
Edit: following #Alnitak comment you should also reset the output variable after each inner loop iteration.
First you will need to construct a collection (or object) that contains the element and the count of occurances. Second you will need to iterate the result to find the key that has the highest value.
JSFiddle
function mostFrequentItemCount(collection) {
var output = {};
for (var i = 0; i < collection.length; i++) {
var item = collection[i];
if (!(item in output))
output[item] = 0;
output[item]++;
}
var result = [0, 5e-324];
for (var item in output) {
if (output[item] > result[1]) {
result[0] = parseFloat(item);
result[1] = output[item];
}
}
return result;
}
var input = [3, -1, -1, -1, 2, 3, -1, 3, -1, 2, 4, 9, 3];
var result = mostFrequentItemCount(input);
console.log(result);
The snippet above simply creates a new object (output) which contains a property for each of the unique elements in the array. The result is something like.
2:2
3:4
4:1
9:1
-1:5
So now we have an object with the property for the number and the value for the occurances. Next we then interate through each of the properties in the output for(var item in output) and determine which value is the greatest.
Now this returns an array with the value at index 0 being the number and the value at index 1 being the count of the element.
Check this solution.
var store = [3, -1, -1, -1, 2, 3, -1, 3, -1, 2, 4, 9, 3];
var frequency = {}; // array of frequency.
var max = 0; // holds the max frequency.
var result; // holds the max frequency element.
for(var v in store) {
frequency[store[v]]=(frequency[store[v]] || 0)+1; // increment frequency.
if(frequency[store[v]] > max) { // is this frequency > max so far ?
max = frequency[store[v]]; // update max.
result = store[v]; // update result.
}
}
alert(max);
So this update to your method will return an object with each key and the count for that key in the array. How you format an output to say what key has what count is up to you.
Edit: Updated to include the complete solution to the problem.
function mostFrequentItemCount(collection) {
var copy = collection.slice(0);
var results = {};
for (var i = 0; i < collection.length; i++) {
var count = 0;
for (var x = 0; x < copy.length; x++) {
if (collection[i] == copy[x]) {
count++;
}
}
results[collection[i]] = count;
}
return results;
}
var inputArray = [3, -1, -1, -1, 2, 3, -1, 3, -1, 2, 4, 9, 3];
var occurances = mostFrequentItemCount(inputArray);
var keyWithHighestOccurance = Object.keys(occurances).reduce(function(a, b){ return occurances[a] > occurances[b] ? a : b });
var highestOccurance = occurances[keyWithHighestOccurance];
console.log("Most frequent number in example array is " + keyWithHighestOccurance + ". It occurs " + highestOccurance + " times in the input array.");

Checking whether certain item is in certain array using javascript

I have 10 different arrays. Each array has different numbers.
array1 = [1,2,3,4,5]
array2 = [6,7,8,9,10]
...
array 10 = [51,52,53,54]
let's say I pass in 7. Then I want to know which array it is from and want to return array number. So in this case it is going to be 2.
Should I write a switch statement for each array? Appreciate it in javascript.
try:
var arrays = [array1, array2, ..., array10];
for(var i=0; i<arrays.length; ++i) {
if (arrays[i].indexOf(value) != -1) {
console.log('found in array' + (i+1));
}
}
You cannot directly retrieve the name of array.The reason is this variable is only storing a reference to the object.
Instead you can have a key inside the same array which represent its name. Then indexOf can be used to find the array which contain the number , & if it is so, then get the array name
var array1 = [1,2,3,4,5];
array1.name ="array1";
var array2 = [6,7,8,9,10];
array2.name ="array2";
var array10 = [51,52,53,54]
array10.name ="array10";
var parArray = [array1,array2,array10]
function _getArrayName(number){
for(var o=0;o<parArray.length;o++){
var _tem = parArray[o];
if(parArray[o].indexOf(number) !==-1){
console.log(parArray[o].name);
}
}
}
_getArrayName(6) //prints array2
jsfiddle
One fast method should be using hash tables or as i would like to call LUT. Accordingly this job boils down to a single liner as follows;
var arrs = {
arr1 : [1,2,3,4,5],
arr2 : [6,7,8,9,10],
arr3 : [12,14,16,17],
arr4 : [21,23,24,25,27,20],
arr5 : [31,34,35,39],
arr6 : [45,46,44],
arr7 : [58,59],
arr8 : [66,67,69,61],
arr9 : [72,73,75,79,71],
arr0 : [81,85,98,99,90,80]
},
lut = Object.keys(arrs).reduce((p,c) => {arrs[c].forEach(n => p[n]=c); return p},{}),
findar = n => lut[n];
document.write("<pre>" + findar(12) + "</pre>");
One way to do this is have the arrays in an object and iterate over the keys/values. This method doesn't presume the arrays (and therefore their names) are in sequential order.
Note: this will always return a the first match from the function and terminate the search.
var obj = {
array1: [1, 2, 3, 4, 5],
array2: [6, 7, 8, 9, 10],
array3: [51, 52, 53, 54],
array4: [51, 52, 53, 54, 7]
}
function finder(obj, test) {
var keys = Object.keys(obj);
for (var i = 0; i < keys.length; i++) {
var key = keys[i];
if (obj[key].indexOf(test) > -1) {
return key.match(/\d+/)[0];
}
}
return false;
}
finder(obj, 7); // '2'
DEMO
If you want to find all instances of a value in all arrays the function needs to be altered slightly.
function finder(obj, test) {
var keys = Object.keys(obj);
var out = [];
for (var i = 0; i < keys.length; i++) {
var key = keys[i];
if (obj[key].indexOf(test) > -1) {
out.push(key.match(/\d+/)[0]);
}
}
return out;
}
finder(obj, 7); // ['2', '4']
DEMO

breaking an array into subsets

I am trying to get this function to split an array into subsets. each subset is to have numbers that are equal to the previous or within 1 from the previous number.
The example I have below should return two subsets but it returns {0, 1, 2, 3} instead. Any idea on what I am doing wrong? Also, is there a better way to dynamically create an array for each new subset? Thanks
function max_tickets() {
var arr = [4, 13, 2, 3];
var myarr = arr.sort(function(a, b){return a-b});
for(var i = 0; i<myarr.length; i++){
var iplus = i+1;
if(i === i || i === iplus){
newArr= [];
newArr.push(i);
}else if (i !== i || i !== iplus){
arr2 =[];
arr2.push(i);
}
}
}
What you are trying to do is usually called "partitioning". The generic version of the problem is to partition an array into sub-arrays using some "rule", or predicate, or condition, which specifies which partition a particular element is supposed to go into, or specifies that it should go into a new partition.
The pseudo code for doing this would be:
To partition an array:
Initialize the resulting array
For each element in the array
If that element starts a new chunk
Create a new empty chunk in the resulting array
Add the element to the most recent chunk
Return the result
This can be expressed in JS quite straightforwardly as
function partition(array, fn) {
return array.reduce((result, elt, i, a) => {
if (!i || !fn(elt, i, a)) result.push([]);
result[result.length - 1].push(elt);
return result;
}, []);
}
Now we need to write the function saying when a new partition should start:
// Is the element within one of the previous element?
function close(e, i, a) {
return Math.abs(e - a[i-1]) > 1;
}
We can now partition the array with
partition([[4, 13, 2, 3], close)
This should work.
function max_tickets() {
var arr = [4, 13, 2, 3];
var myarr = arr.sort(function (a, b) { return a - b });
arrSubsets = [];
arr1 = [];
for (var i = 0; i < myarr.length; i++) {
if (myarr[i - 1] === undefined) {
arr1.push(myarr[i]);
continue;
}
if (myarr[i] - myarr[i - 1] <= 1) {
arr1.push(myarr[i]);
}
else {
arrSubsets.push(arr1);
arr1 = [];
arr1.push(myarr[i]);
}
}
if (arr1.length > 0)
arrSubsets.push(arr1);
}
max_tickets();
Based on your questions:
Any idea on what I am doing wrong?.
Inside of your loop you are using i as if it is the value of the array, but the loop goes from 0 to the value of myarr.length in your particular case 4, so that makes the value of i to be 0, 1, 2, 3.
As you can see you are using the values of the index to compare, instead of using the values of the array in order to use the values of the array you must specify the arrayname[index], in your case myarr[i] that will give you the values: 4, 13, 2, 3.
Also, is there a better way to dynamically create an array for each new subset?
Yes you can create an array inside of another array dynamically inside of a loop:
var b = [];
for(var i = 0; i < 10; i++){
b.push(['I am' + i, i]);
}
As you can see in the previous example I'm creating an array inside of the b array so once the loop finishes the b array will have 10 arrays inside of it with 2 elements each.

Categories

Resources