I need to read all the connection times. (connectionTimes)
I need to delete the line - when it will be offline more than online:
userId: 1,
connectionTimes:
[
{onlineTime:"11:10:30", offlineTime:"11:18:12"}, //delete
{onlineTime:"11:14:14", offlineTime:"11:52:41"} //delete
]
Delete user id - When times the connection will be empty.
userId: 1, //delete userid
connectionTimes:
[
//empty connection
]
I have this data structure:
var users = [];
users[0] = {
userId: 1,
connectionTimes:
[
{onlineTime:"11:10:30", offlineTime:"11:18:12"},
{onlineTime:"11:14:14", offlineTime:"11:52:41"}
]
}
users[1] = {
userId: 2,
connectionTimes:
[
{onlineTime:"8:08:14", offlineTime:"1:15:00"}
]
}
You can delete a property from an JavaScript object with the delete operator:
var sampleObject = {
"key1": "value1",
"key2": "value"
};
delete sampleObject["key2"];
or like this:
delete sampleObject.key2
See the Mozilla Developer Network JavaScript Reference for more background on the delete operator:
https://developer.mozilla.org/en/JavaScript/Reference/Operators/delete
Your specific example would look something like this:
for(var id in users) {
var user = users[id];
if (user.connectionTimes.length === 0) {
delete users[id];
break
}
for(var i=0; i<=user.connectionTimes.length; i++) {
var connectionTime = user.connectionTimes[i];
if (connectionTime.onlineTime < connectionTime.offlineTime) {
delete users[id];
break;
}
}
}
Here is a link to jsFiddle showing the code in action:
http://jsfiddle.net/Q86Jd/
There are many ways to remove things from arrays in Javascript. The mains ones I can think of are
The delete operator. Using it sets the chosen position to undefined and is similar to just setting the element to null. (The main difference is that deleting a key will cause it to be skiped when iterating with the forEach and map array methods).
var xs = [0,1,2];
delete xs[1];
console.log(xs); // [0, undefined, 2]
The splice method can remove a chunk or the array, moving the remaining elements left to fill it in.
var xs = [0,1,2,3];
xs.splice(2, 1); //index, ammount to remove
console.log(xs); // [0,1,3]
Setting the array's length property truncates it. This can be used to manually remove elements the old fashioned way when you want more control.
var xs = [0,1,2,3];
xs.length = 2;
console.log(xs); // [0,1]
xs.length = 4;
console.log(xs); // [0,1, undefined, undefined]
So in your case we might do something like this:
function filter_in_place(array, predicate){
var j=0;
for(var i=0; i<arr.length; i++){
var x = arr[i];
if(pred(x)){
arr[j++] = x;
}
}
arr.length = j;
}
for(var i=0; i < users.length; i++){
filter_in_place( users[i].connections, function(conn){
/*return if offline larger then online*/
});
}
filter_in_place(users, function(user){ return user.connections.length > 0; });
Basically you want to use something like this:
for( var i=0; i<users.length; i++) {
for( var j=0; j<users[i].connectionTimes.length; j++) {
if( users[i].connectionTimes[j].onlineTime < users[i].connectionTimes[j].offlineTime) {
delete users[i].connectionTimes[j];
j--;
}
}
if( users[i].connectionTimes.length == 0) {
delete users[i];
i--;
}
}
This is pretty straightforward. In pseudocode:
declare user, times
for each index in users
set user = users[ index ]
set times = user.connectionTimes
if times is empty
then delete users[ index ]
else
declare onlineSecs, offlineSecs
for each index2 in times
set onlineSecs = timeInSeconds( times[ index2 ].onlineTime )
set offlineSecs = timeInSeconds( times[ index2 ].offlineTime )
if offlineSecs > onlineSecs
then delete times[ index2 ]
In JavaScript the command to delete a variable is delete and can be used on arrays the same, e.g. delete someArray[ someIdx ];. The implementation of timeInSeconds will be something like this:
function timeInSeconds( timeWithColons ) {
var hrsMinsSecs = "12:34:56".split(':');
return ( parseInt( hrsMinsSecs[0] ) * 60 +
parseInt( hrsMinsSecs[1] )
) * 60 +
parseInt( hrsMinsSecs[2] )
;
}
Related
this seems pretty silly to ask but I'm moving a bit away from PHP to javascript and have a bit of a hard time with 2 arrays one the original values and the other the new values.
I need to take take action on any values removed (run some function) and on any new values that where added.
Here is what I came up with so far, but it doesn't seem right.
// new values
var array1 = [ 'aaaa', 'R26i9vjDHE', 'bbbbb' ];
// original values
var array2 = [ 'U8G5AQVsX6', 'R26i9vjDHE', '7IkuofIHEu','aaaa'];
for (var i = 0; i < array2.length; i++) {
if(array1.indexOf(array2[i]) != -1) {
console.log('in new already?');
console.log(array2[i])
// do something with new inserted value
} else {
console.log('removed items');
console.log(array2[i])
// do something with a removed value
}
}
I'm used to php's in_array in a loop or various other php tool box items.
Suggestions?
my fiddle https://jsfiddle.net/xv8ah2yf/8/
So an element that was removed will be in array2, but not array1, and then an element added will be in array1 but not array2. So to detect both cases you'll need to loop through both arrays. You can do something like
var i;
for (i = 0; i < array2.length; i++) {
if (array1.indexOf(array2[i]) === -1) {
//item removed from array2
console.log(array2[i] + ' removed');
}
}
for (i = 0; i < array1.length; i++) {
if (array2.indexOf(array1[i]) === -1) {
//item added to array1
console.log(array1[i] + ' added');
}
}
Then take the appropriate action when each case is detected.
Let's just define what is meant be "added" and "removed":
added: in new array but not in original.
removed: in original but not in new array.
We can use 2 for-loops to determine these two types of elements:
let original_array = ['abc', 'def', 'ghi'];
let new_array = ['def', 'jkl', 'mno'];
for (let i = 0; i < new_array.length; i++){
if (!original_array.includes(new_array[i])){
console.log(new_array[i], 'has been added');
//further actions...
}
}
for (let i = 0; i < original_array.length; i++){
if (!new_array.includes(original_array[i])){
console.log(original_array[i], 'has been removed');
//further actions...
}
}
This should do it:
function compute(original, modified, addedCB, removedCB) {
for (let i of modified) {
if (!original.includes(i)) {
// this is a new value
addedCB(i);
}
}
for (let i of original) {
if (!modified.includes(i)) {
// the modified array doesn't include this value
removedCB(i);
}
}
}
You can get close to PHP's in_array with javascript's array.includes. You can use that to then filter the arrays in question:
This is a little slower than doing everything in a for loop, but also more succinct and cleared (IMO):
// new values
var array1 = [ 'aaaa', 'R26i9vjDHE', 'bbbbb' ];
// original values
var array2 = [ 'U8G5AQVsX6', 'R26i9vjDHE', '7IkuofIHEu','aaaa'];
// in array1 but not in array2
let not_in_array2 = array1.filter(item => !array2.includes(item))
// in array2 but not in array1
let not_in_array1 = array2.filter(item => !array1.includes(item))
// in both arrays
let inBoth = array1.filter(item => array2.includes(item))
console.log("Not in array1:", not_in_array1)
console.log("Not in array2:", not_in_array2)
console.log("In both:", inBoth)
From there you can forEach() or map() over the results and apply whatever function you want.
EDIT - 2 elegant solutions
Two elegant solutions, from Pranav and Bekim. Thanks, both tested and worked perfectly.
One
for(var x in data)data[x].name == "other" ? data.push( data.splice(x,1)[0] ) : 0;
Two
var res = data.slice(),
len = res.length;
for (var i = 0; i < len; i++) {
if (res[i].name == 'other') {
res.push(res.splice(i, 1)[0]);
i--;
len--;
}
}
JS TOOLS IM USING
Angular 1.5.6, lodash 4.1x
Here is the scenario I have an array of objects sorted alphabetically e.g. sortedData below etc.. However, within that array is also the catch all Other which is obviously sorted alphabetically as well. I want to remove other from the array and then move to the end of array without messing with the current sorted array.
NOTE
My current approach below works but is ugly. Does JS, angular or lodash have something more elegant?
var data = [
{id:1,name:'apple'},
{id:2,name:'banana'},
{id:3,name:'other'},
{id:4,name:'tomato'},
{id:5,name:'strawberry'}
];
function move(array, fromIndex, toIndex) {
array.splice(toIndex, 1, array.splice(fromIndex, 1)[0]);
return array;
}
var moved = move(
data,
_.findIndex(data, ['name', 'other']),
Object.keys(data).length
);
Ideal Outcome
var data = [
{id:1,name:'one'},
{id:2,name:'two'},
{id:4,name:'four'},
{id:5,name:'five'}
{id:3,name:'other'},
]
You do Array.findIndex in pure Javascript (ES6), without using any libs:
data.push(data.splice(data.findIndex(v => v.name == 'other'), 1)[0])
Array.findIndex is new, but most browsers people actually use these days have it. So you can probably use it. (Edge supports it, but not IE).
If you find the [0] ugly, you can use spread to unpack the array (that way it'll also work for more than one item with some changes):
data.push(...data.splice(data.findIndex(v => v.name == 'other'), 1))
A plain (Vanilla) JavaScript will do just fine:
for(var x in data)data[x].name == "other" ? data.push( data.splice(x,1)[0] ) : 0;
var data = [
{id:1,name:'apple'},
{id:2,name:'banana'},
{id:3,name:'other'},
{id:4,name:'tomato'},
{id:5,name:'strawberry'}
];
for(var x in data)data[x].name == "other" ? data.push( data.splice(x,1)[0] ) : 0;
console.log( data );
Use simple for loop
var data = [{
id: 1,
name: 'apple'
}, {
id: 2,
name: 'banana'
}, {
id: 3,
name: 'other'
}, {
id: 4,
name: 'tomato'
}, {
id: 5,
name: 'strawberry'
}];
// store the length of array
var len = data.length;
// iterate over all array elements
for (var i = 0; i < len; i++) {
// check value is `other`
if (data[i].name == 'other') {
// if value is other then move the object
data.push(data.splice(i, 1)[0]);
// decrement i since the element removed
i--;
// decrement len to avoid moved element
len--;
}
}
console.log(data);
I've read a lot of articles about objects and arrays lately but they had contrary info / facts for some reason. I need your help to learn once and for all: when it's best to use array and when object?
Obvious reason is to use array when you need specific order. What else? What about this example?
There's a lot of pushing
There's a lot of checking if array contains something
There's a lot of removing
Note that this example has much smaller numbers that I need (which is in thousands).
Code I wrote for this question, it has few things I would never do but for the sake of this question:
var x = [];
var y = [];
var z = [];
var clickedX = [];
var clickedY = [];
var clickedZ = [];
var count = 100;
for ( var a = 0; a < count; a++ ) {
//For the sake of this example: random int 1, 2 or 3
var type = Math.floor(Math.random() * 3) + 1;
createDiv( type );
}
function createDiv( thisType ) {
var self = this;
var div = self.div;
var type = thisType;
if( !div ) {
div = this.div = document.createElement( 'div' );
div.className = 'marker';
//Push to "right" array
if( type == '1' ) {
x.push( self );
}
else if ( type == '2' ) {
y.push( self );
}
else {
z.push( self );
}
//Attach click event
div.onclick = function() {
// X
var indexX = x.indexOf( self );
if( indexX > -1 ) {
//Push to new array
clickedX.push( self );
//Remove from old array
x.splice( indexX, 1 );
}
// Y
var indexY = y.indexOf( self );
if( indexY > -1 ) {
//Push to new array
clickedY.push( self );
//Remove from old array
y.splice( indexY, 1 );
}
// Z
var indexZ = z.indexOf( self );
if( indexZ > -1 ) {
//Push to new array
clickedZ.push( self );
//Remove from old array
z.splice( indexZ, 1 );
}
}; // onclick
} // if( !div )
} // createDiv()
Data example what Im currently dealing with:
// Data Im dealing with
objects = {
{ objects1: [
0: { object : [4-5 assigned values (int, string, array)] },
1: { object : [4-5 assigned values (int, string, array)] },
//etc
]
},
{ objects2: [
0: {object},
1: {object},
//etc
]
}
}
// 1. I need to iterate through every "object" in both "objects1" and "objects2"
// 2. I need to iterate through "array" in every "object" in "objects1"
for( /* "object" count in "objects1" */ ) {
//Do something for each "object" in "objects1"
for( /* items in "array" count */ ) {
//Do something for each item in "array"
}
}
// AND
for( /* "object" count in "objects2" */ ) {
//Do something for each "object" in "objects2"
}
Arrays
Basically, you need to use an array, when you have a list of consequent data, and you are going to work with it as a collection.
It easily adds, iterates, gets count and checks for existence.
It is difficult to remove items in an array.
Also, it stores order.
For example, if you have 10 integers, and you need to find the index of the minimum one, then it is logical to use an array.
Objects
Use objects, when your items have keys (especially, non-integer) and you are going to work with them one by one.
It is convenient to add, remove, check for existence properties.
However, it is less convenient to iterate through object properties, and absolutely inproper to get its count.
It is also impossible to store items' order.
Time complexity
Answering your question about pushing, checking for existence and removing:
Both property setting and array pushing takes O(1) time, but I strongly believe that the first one is a bit slower
Checking for existence takes the same O(1) time
Removing an element is what array is not designed for - it needs to shift all items and takes O(n) time, while you can remove a property for O(1)
Bad usage example
There are some really bad usages. If you have the following, then you use array or object wrong.
Assign a random value to an array:
var a = [];
a[1000] = 1;
It will change the length property of an array to 1001 and if you try to output this array, you will get the following:
[undefined,undefined,undefined,undefined... 1]
which is absolutely useless, if it is not done on purpose.
Assign consequent values to an object
var a = {};
for (var i = 0; i < 10; i++)
{
a[i] = 1;
}
Your code
Talking about your code, there are many and many ways to do this properly - just choose one. I would do it in the following way:
var items = [];
for (var i = 0; i < count; i++)
{
var o = {
type: Math.floor(Math.random() * 3) + 1,
isClicked: false
};
var div = document.createElement('div');
div.className = 'marker';
div.onclick = function() {
o.isClicked = true;
};
o.div = div;
items.push(o);
}
function GetDivs(type, isClicked)
{
var result = items;
if (type)
result = result.filter(function(x) { return x.type === type; });
if (isClicked !== undefined)
result = result.filter(function(x) { return x.isClicked === isClicked; });
return result;
}
Then, you will be able to get any items you want:
var all = GetItems(0); // or even GetDivs()
var allClicked = GetItems(0, true);
var allNotClicked = GetItems(0, false);
var divsTypeA = GetItems(1);
var clickedDivsTypeB = GetItems(2, true);
var notClickedDivsTypeC = GetItems(3, false);
With this usage, you don't need to remove any items at all - you just mark them as clicked or not, which takes O(1) time.
jQuery
If you use jQuery and data HTML attributes, then you won't need to use arrays or objects at all:
for (var i = 0; i < count; i++)
{
$('<div/>')
.addClass('marker')
.attr('data-type', Math.floor(Math.random() * 3) + 1)
.appendTo('body')
.click(function() {
$(this).addClass('clicked');
});
}
Now, you can use the selector to find any items:
var all = $('.marker');
var allClicked = $('.marker.clicked');
var allNotClicked = $('.marker:not(.clicked)');
var divsTypeA = $('.marker[data-type='1']');
var clickedDivsTypeB = $('.marker[data-type='2'].clicked');
var notClickedDivsTypeC = $('.marker[data-type='1']:not(.clicked)');
However, the last approach can produce lags if you really have thousands of records. At the same time, is it a good idea to have 1000 dynamic divs on your page, at all? :)
When all else fails run a test, Again it depends on what you intend to use the data structure for, everything is a trade off, performance || efficiency.
Be prepared to wait a few seconds for the tests to finish.
function gimmeAHugeArray( length ){
var arr = [];
for( var ii = 0; ii < length; ii++ ){
arr.push( (ii * 100000 ).toString(16) );
}
return arr;
}
function gimmeAHugeObject( length ){
var obj = {};
for( var ii = 0; ii < length; ii++ ){
obj[ (ii * 100000 ).toString(16) ] = ii;
}
return obj;
}
var hugeArray = gimmeAHugeArray( 100000 );
var hugeObject = gimmeAHugeObject( 100000 );
var key = (8000 * 100000).toString(16);
console.perf(function arrayGetWithIndexOf(){
var val = hugeArray.indexOf( key );
});
console.perf(function objectGetWithKey(){
var val = hugeObject[ key ];
});
console.perf(function arrayIterateAllProperties(){
var val = null;
for( var ii = 0, ll = hugeArray.length; ii < ll; ii++ ){
val = hugeArray[ii];
}
}, 50);
console.perf(function objectIterateAllProperties(){
var val = null,
key;
for( key in hugeObject ){
val = hugeObject[ key ];
}
}, 50);
<script src="http://codepen.io/synthet1c/pen/WrQapG.js"></script>
I'm going to answer your question from the comment above, from Solo.
The question is What to do if I need to do both with same data?
I have found that the best approach ( at least for me ) was to create an array, that may have empty nodes, but keep another array that will keep track of the ids that are populated.
It looks something like this:
var MyArray = function()
{
this.storage = [];
this.ids = [];
};
MyArray.prototype.set = function(id, value)
{
this.storage[id] = value;
this.ids[this.ids.length] = id;
};
MyArray.prototype.get = function(id)
{
return this.storage[id];
};
MyArray.prototype.delete = function(id)
{
delete this.storage[id];
};
This solution works quite well with both approaches, because you can delete anything at O(1), because everyone has a given ID, and you iterate it easily, because you have all of the IDs the values are stored at.
I have also created a really small class for my own usage, and it performs VERY well. Here's the link https://github.com/ImJustAskingDude/JavascriptFastArray . Here's a question I asked about these things: Javascript Array Performance .
Please read what I write there, this solution applies to a pretty particular situation, I do not know exactly if it applies to you.
That is why I asked you to read what is in those links I provided, I have written like 10 pages worth of material on this, even though some of it is pure garbage talk about nothing. Anyway, I'll write a couple of examples here as well, then.
Example:
Let us say you had data from the database, the data from the database is pretty much required to have unique integer IDs, but each user may have them spread over a wide range, they are MOST LIKELY not contiguous.
So you get the data from the database into objects, something like this:
var DBData /* well, probably something more descriptive than this stupid name */ = function(id, field1, field2, field3)
{
this.id = id;
this.field1 = field1;
this.field2 = field2;
this.fiedl3 = field3;
};
Given this class, you write all of the data from the database into instances of it, and store it in MyArray.
var data = new MyArray();
// YOU CAN USE THIS, OR JUST READ FROM DOM
$.get(/* get data from DB into MyArray instance */, function(data) { /* parse it somehow */ var dbdata = new DBData(/* fields that you parsed including ID */); data.set(ID, dbdata)});
and when you want to iterate over all of the data, you can do it like this:
Just create a function to create a new array, that has all of the data in a nice contiguous block, it would go something like this:
function hydrate(myarray, ids)
{
var result = [];
var length = ids.length;
if(!length)
{
return null;
}
var storage = myarray.storage;
for(var i = 0; i < length; i++)
{
result[result.length] = storage[ids[i]];
}
return result;
};
I use this method, because you can use it to select any configuration of objects into a contiguous array very easily.
One solution to handle arrays of arrays, would be to just modify MyArray to deal with that exclusively, or make a version of it, that handles it.
A different solution would be to rethink your approach, and maybe add all of the data in a single MyArray, but put all of the
objects1: [
0: { object : [4-5 assigned values (int, string, array)] },
1: { object : [4-5 assigned values (int, string, array)] },
//etc
]
},
{ objects2: [
0: {object},
1: {object},
//etc
]
}
into nice objects.
And seriously, read what I wrote in those links, there's my reasoning for everything there.
I have a node system, which stores a bunch of nodes that are connected to other nodes. The data is structured like this:
[
{"id":0,"x":1,"y":2, "linksTo":[1]},
{"id":1,"x":3,"y":4, "linksTo":[0,2,3]},
{"id":2,"x":5,"y":6, "linksTo":[1,4]},
{"id":3,"x":3,"y":10,"linksTo":[1,4]},
{"id":4,"x":5,"y":12,"linksTo":[2,3]}
]
What I'm trying to do is delete a certain node, and all references to that in the other nodes that might be "linked" to it based on its ID.
I've gotten to the point where I can get the node i need using this function:
function getNode(id, y){
var x;
if(y){ x = id; }
if(x && y){
var nodeAtPos = false;
Object.keys(paths.list).forEach(function(i){
if(paths.list[i].x == x && paths.list[i].y == y){
nodeAtPos = paths.list[i];
return false;
}
return true;
});
return nodeAtPos;
}
return paths.list[id];
}
function deleteNode(x,y){
var obj = getNode(x,y);
//need to delete obejct and delete key references in other objects that were connected to it
}
deleteNode(5,12);
The end result would look like this in my data structure:
[
{"id":0,"x":1,"y":2, "linksTo":[1]},
{"id":1,"x":3,"y":4, "linksTo":[0,2,3]},
{"id":2,"x":5,"y":6, "linksTo":[1]}, //changed
{"id":3,"x":3,"y":10,"linksTo":[1]}, //changed
]
But as you can see in my data strucutre, if I simply delete it, I still have a few nodes that linksTo to it that I need to clean up. Otherwise they will be linked to non existant nodes.
What would be the simplest way to do this?
You could iterate each object and do the following operations:
Check if the node has its link to it. If so remove it from its
linkTo.
During the iteration, keep track of the index of the node which has
its id as the node to be deleted.
Once the iteration is done, remove the node from the array.
Code:
var x = [
{"id":0,"x":1,"y":2, "linksTo":[1]},
{"id":1,"x":3,"y":4, "linksTo":[0,2,3]},
{"id":2,"x":5,"y":6, "linksTo":[1,4]},
{"id":3,"x":3,"y":10,"linksTo":[1,4]},
{"id":4,"x":5,"y":12,"linksTo":[2,3]}
];
var index = -1;
var toDel = 2;
for(var i=0;i<x.length;i++){
if(x[i]["linksTo"].indexOf(toDel) != -1){
x[i]["linksTo"].splice(x[i]["linksTo"].indexOf(toDel),1);
}
if(x[i]["id"] == toDel){index = i;}
}
if(index != -1){
x.splice(index, 1);
}
console.log(x);
There is no other way, but to update the linksTo value for the rest of elements
var deletedId = 4;
var arr = [
{"id":0,"x":1,"y":2, "linksTo":[1]},
{"id":1,"x":3,"y":4, "linksTo":[0,2,3]},
{"id":2,"x":5,"y":6, "linksTo":[1,4]},
{"id":3,"x":3,"y":10,"linksTo":[1,4]},
];
for (var i=0 ; i < arr.length ; i++ ) {
var node = arr[i];
var newRef = [];
for (var l=0 ; l < node.linksTo.length; l++) { // l is an index for links
if (node.linksTo[l] != deletedId)
newRef.push(node.linksTo[l])
}
node.linksTo = newRef; // assign new array
}
I need to know if one or more duplicates exist in a list. Is there a way to do this without travelling through the list more than once?
Thanks guys for the suggestions. I ended up using this because it was the simplest to implement:
var names = [];
var namesLen = names.length;
for (i=0; i<namesLen; i++) {
for (x=0; x<namesLen; x++) {
if (names[i] === names[x] && (i !== x)) {alert('dupe')}
}
}
Well the usual way to do that would be to put each item in a hashmap dictionary and you could check if it was already inserted. If your list is of objects they you would have to create your own hash function on the object as you would know what makes each one unique. Check out the answer to this question.
JavaScript Hashmap Equivalent
This method uses an object as a lookup table to keep track of how many and which dups were found. It then returns an object with each dup and the dup count.
function findDups(list) {
var uniques = {}, val;
var dups = {};
for (var i = 0, len = list.length; i < len; i++) {
val = list[i];
if (val in uniques) {
uniques[val]++;
dups[val] = uniques[val];
} else {
uniques[val] = 1;
}
}
return(dups);
}
var data = [1,2,3,4,5,2,3,2,6,8,9,9];
findDups(data); // returns {2: 3, 3: 2, 9: 2}
var data2 = [1,2,3,4,5,6,7,8,9];
findDups(data2); // returns {}
var data3 = [1,1,1,1,1,2,3,4];
findDups(data3); // returns {1: 5}
Since we now have ES6 available with the built-in Map object, here's a version of findDups() that uses the Map object:
function findDups(list) {
const uniques = new Set(); // set of items found
const dups = new Map(); // count of items that have dups
for (let val of list) {
if (uniques.has(val)) {
let cnt = dups.get(val) || 1;
dups.set(val, ++cnt);
} else {
uniques.add(val);
}
}
return dups;
}
var data = [1,2,3,4,5,2,3,2,6,8,9,9];
log(findDups(data)); // returns {2 => 3, 3 => 2, 9 => 2}
var data2 = [1,2,3,4,5,6,7,8,9];
log(findDups(data2)); // returns empty map
var data3 = [1,1,1,1,1,2,3,4];
log(findDups(data3)); // returns {1 => 5}
// display resulting Map object (only used for debugging display in snippet)
function log(map) {
let output = [];
for (let [key, value] of map) {
output.push(key + " => " + value);
}
let div = document.createElement("div");
div.innerHTML = "{" + output.join(", ") + "}";
document.body.appendChild(div);
}
If your strings are in an array (A) you can use A.some-
it will return true and quit as soon as it finds a duplicate,
or return false if it has checked them all without any duplicates.
has_duplicates= A.some(function(itm){
return A.indexOf(itm)===A.lastIndexOf(itm);
});
If your list was just words or phrases, you could put them into an associative array.
var list=new Array("foo", "bar", "foobar", "foo", "bar");
var newlist= new Array();
for(i in list){
if(newlist[list[i]])
newlist[list[i]]++;
else
newlist[list[i]]=1;
}
Your final array should look like this:
"foo"=>2, "bar"=>2, "foobar"=>1