Assuming I have two Javascript Objects (they have a JSON structure, but are created with JSON.parse()). All entries have a unique ID with which the entries from both objects can be matched.
What would be the fastest way to join both objects (native javascript).
The first thing that comes into my mind would be a nested for in loop.
for(var i in firstJson) {
for(var j in secondJson) {
if(firstJson[i].id === secondJson[j].id) {
// join them
}
}
}
Is there a faster way?
More efficient way would be to create an index out of one of them:
var index = {};
for (var j in secondJson) {
var obj = secondJson[j];
index[obj.id] = obj;
};
for (var i in firstJson) {
var firstObj = firstJson[i];
var match = index[firstObj.id];
if (match) {
// do the stuff
}
};
This is O(n+m) instead of O(n*m) for nested loops. At the cost of O(m) memory of course.
If both lists are not already sorted you could first sort them by id, then do the comparison and saving the position of the last found object, starting from the last found if nothing was found.
(I do believe that the solution from freakish is faster, but this has no extra memory consumption)
This should be on the order O(nlog(n)+mlog(m)+m)
first.Sort();
second.Sort();
int idx = 0;
int lastIdx = 0;
for (int i = 0; i < first.Count; i++) {
for (int j = idx; j < second.Count; j++)
{
if (first[i] == second[j])
{
Console.WriteLine("equal " + first[i]);
idx = j + 1;
lastIdx = idx;
break;
}
}
if (idx == second.Count)
idx = lastIdx;
}
I am having some random JSON data at the moment, therefore I cannot using standrad way to do it, cannot do it one by one.
For example if i am going to store specific data as array i will do something like below
var tester = []; // store their names within a local array
for(var k = 0; i < data.result.length; i++){ //maybe 6
for(var i = 0; i < data.result.data.length; i++){ //maybe 30 times in total
tester.push(data.result[k].data[i].someNames);
}
}
But since I cannot predict how many set of data i have i can't really do something like
var tester = [];
var tester2 = [];
var tester3 = [];
var tester4 = [];
for(var i = 0; i < data.result.data.length; i++){ //maybe 30 times in total
tester.push(data.result[0].data[i].someNames);
tester2.push(data.result[1].data[i].someNames);
tester3.push(data.result[2].data[i].someNames);
tester4.push(data.result[3].data[i].someNames);
}
if there' any better way which using for loop to store these data?
Make tester a 2-dimensional array and use nested loops.
var tester = [];
for (var i = 0; i < data.result.length; i++) {
var curTester = [];
var result = data.result[i];
for (var j = 0; j < result.data.length; j++) {
curTester.push(result.data[j].someNames);
}
tester.push(curTester);
}
Some general principles:
Any time you find yourself defining variables with numeric suffixes, they should probably be an array.
When you don't know how many of something you're going to have, put them in an array.
I am looking at an underscore.js function to retrieve the values from an object and am curious to understand the reason the _.values function was created the way it was.
The function as is in underscore.js:
_.values = function(obj) {
var keys = _.keys(obj);
var length = keys.length;
var values = Array(length);
for (var i = 0; i < length; i++) {
values[i] = obj[keys[i]];
}
return values;
};
I believe this would also work however:
_.values = function(obj) {
var keys = _.keys(obj);
var length = keys.length;
var values = [];
for (var i = 0; i < length; i++) {
values.push(obj[keys[i]]);
}
return values;
};
What is the tradeoff between using function #1 vs. #2. Is it simply for performance or is there other things?
Thanks.
The first approach allows the JS runtime to immediately allocate the correct amount of memory.
Calling push() on an empty array will force the array to resize as it gets full, wasting time and memory.
What I want to do:
Search through a multi-dimensional array using multiple search strings.
Example of what I am currently doing:
var multiArray = [['Apples and pears', 'tuna salad'],['bananas tuna'],['the colour blue']];
var singleArray = [];
var match_array = [];
// Turn multiple arrays into one big one
for (var i = 0; i < multiArray.length; i++) {
for (var x = 0; x < multiArray[i].length; x++) {
singleArray.push(multiArray[i][x]);
}
}
// Create a new array from matched strings
function find_match(to_match) {
for (var i in singleArray) {
if (singleArray[i].indexOf(to_match)!= -1)
match_array.push(singleArray[i]);
}
return (match_array.length === 0 ? null : match_array);
}
// Find matching terms for match_array
find_match('tuna');
find_match('the');
alert(match_array);
JSFiddle Demo
Questions:
Obviously this is a cluttered way of doing this. How can this be
streamlined(i.e. searching the multiArray directly and not using
multiple find_match functions)?
How can I get only the exact string matches, preferably without breaking up the multi-dimensional array?
What are your thoughts about searching through massive
multidimensional arrays?
Do you want something like this?
var multiArray = [['Foo', 'Bar'],['Foo'],['Bar']];
var singleArray = [];
var match_array = [];
// Turn multiple arrays into one big one
for (var i = 0; i < multiArray.length; i++) {
for (var x = 0; x < multiArray[i].length; x++) {
singleArray.push(multiArray[i][x]);
}
}
// Create a new array from matched strings
function find_match(to_match, where_search) {
for (var j in where_search) {
if(where_search[j] instanceof Array){
find_match(to_match, where_search[j]);
}else{
for (var i in to_match) {
if (where_search[j].indexOf(to_match[i]) ==0 &&
where_search[j].length == to_match[i].length)
match_array.push(where_search[j]);
}
}
}
return (where_search.length === 0 ? null : match_array);
}
// Find matching terms for match_array
find_match(['Foo', 'Bar'],multiArray);
alert(match_array);
I'm trying to implement a duplicate method to the js Array prototype which concats a duplicate of the array to itself like so:
[11,22,3,34,5,26,7,8,9].duplicate(); // [11,22,3,34,5,26,7,8,9,11,22,3,34,5,26,7,8,9]
Here's what I have, but it causes the browser to crash:
var array = [11,22,3,34,5,26,7,8,9];
Array.prototype.duplicate = function() {
var j = this.length;
for(var i = 0; i < this.length; i++) {
this[j] = this[i];
j++;
}
return this;
}
I'm trying to do this using native JS as practice for iterations and algorithms so I'm trying to avoid built-in methods, if possible, so that I can get a clearer understanding of how things are being moved around.
Any ideas on why it is crashing and how I can optimize it?
The code inside the loop changes the length of the array, so it will just keep growing and you will never reach the end of it. Get the initial length of the array in a variable and use in the loop condition. You can use that as offset for the target index also instead of another counter:
var array = [11,22,3,34,5,26,7,8,9];
Array.prototype.duplicate = function() {
var len = this.length;
for (var i = 0; i < len; i++) {
this[len + i] = this[i];
}
return this;
}
The length of the array is increasing with each element added so you can not use this as a terminator. Try this.
var j = this.length;
for(var i = 0; i < j; i++) {
this[i+j] = this[i];
}
Here's simplest code
Array.prototype.duplicate = function () {
var array = this;
return array.concat(array);
};
Using Spread syntax;
In a method, this refers to the owner object.
Array.prototype.duplicate = function () {
return [...this, ...this]
};
let array = [1,2,3,4,5];
Array.prototype.duplicate = function () {
return [...this, ...this]
};
console.log(array.duplicate());