Insert data to array of array - javascript

i have this loop.
now, in a[i] im putting name of college, for example UCLA.
in temp i have the name of the player i want to insert into the a[i][p]
When im looking at temp im seeing the name that i actualy wants to insert, but them im
doing this line a[i][p] = temp;
im seeing in a[0][0]='U',
why?
var a = [[]];
var p = 0;
var temp;
for (var i = 0; i < uniq.length; i++) {
a[i] = uniq[i];
for (var k = 0; k < data.players.length; k++) {
if (uniq[i] == data.players[k].college)
{
temp = data.players[k].name
a[i][p] = temp;
p++;
}
}
p = 0;
}
console.log(a[0][0])

The answer is:
first you put UCLA as the value of a[0]
now your array looks like this:
console.log(a[0]) // expected "UCLA"
strings in JavaScript can be iterated over - this means (roughly), that you can get a[0][0] in this case: the first item of the first item of the a array - and that is "the first character of the string at the first index in a"
console.log(a[0][0]) // expected: "U", if a[0] is "UCLA"
const a = []
a[0] = "UCLA"
console.log(a)
console.log(a[0])
console.log(a[0][0])
You need to do it a bit differently (this could be one approach, but there could be more):
const a = {} // this is an object, not an array!
a["UCLA"] = "name of tthe player"
console.log(a)
console.log(a["UCLA"])
Or, if you need an array, then you could do:
const a = []
a[0] = { uni: "UCLA", player: [] }
a[0].player[0] = "name of the player"
console.log(a)

when indexing JavaScript strings they behave like arrays and you actually get a 1 letter string with the character on the index you requested
for example:
var dummy = "house";
console.log(dummy[1]);
//this is going to return o (character in index 1 of house)
note that when indexing a string you are going to get another string and not a char like in other languages,
to achieve what you are trying to do you can use a dictionary like this:
var schools = {};
for (var i = 0; i < uniq.length; i++) {
schools[uniq[i]] = [];
for (var k = 0; k < data.players.length; k++) {
if (uniq[i] == data.players[k].college)
{
schools[uniq[i]].push(data.players[k].name);
}
}
}
at the end of this you can access schools either by indexing, by string key (college name) or with a simple foreach
schools[1]; //this is gonna give ["firstname","secondname","etc"] (player names of the second school)
schools["UCLA"]; //this is gonna give ["firstname","secondname","etc"] (player names of UCLA school)

Related

How to get longest substring from array of strings using javascript

I have array:
let arr = ["logerror", "log:today", "log:1"]
I am looking for function how to get longest substring from this items.
Result:
log
Another example:
let arr = ["dog+ěě+", "dog15qwqqq", "dogggggg"]
Result:
dog
Sure, I can write some algorithm, but is there any simple way?
How? Thanks
If you can phrase your question succinctly, you can often find what to search for. In this case, it looks like:
"Find the longest common substring from within an array of strings"
A quick google reveals an algorithm for finding the largest common substring between two strings:
https://en.wikibooks.org/wiki/Algorithm_Implementation/Strings/Longest_common_substring
I don't want to copy the code as written there, as unsure of the copyright, but you could take the implementation and take something that will work with your array.
I would note that for large arrays, this may turn out to be a lengthy operation...
I used a simple approach:
It sorts the array using sort() method.
Then, the most important step is to look just at the first and last items.
function commonSubsequence(array){
let sortedArray = array.sort();
let first = sortedArray[0];
let last = sortedArray.pop();
let length = first.length;
let index = 0;
while(index<length && first[index] === last[index])
index++;
return first.substring(0, index);
}
console.log(commonSubsequence(["logerror", "log:today", "log:1"]));
console.log(commonSubsequence(["dog+ěě+", "dog15qwqqq", "dogggggg"]));
Here is my suggestion
function subStrArr(arr) {
let chars = arr[0].split(""), sub = "";
for (let i=0;i<chars.length;i++) {
for (let j=1;j<arr.length;j++) {
if (arr[j].indexOf(chars[i])==-1) return sub;
}
sub+=chars[i];
}
}
let arr1 = ["logerror", "log:today", "log:1"];
let arr2 = ["dog+ěě+", "dog15qwqqq", "dogggggg"];
console.log(subStrArr(arr1))
console.log(subStrArr(arr2))
After some looking around I went for the string-algorithms npm package, which did the job nicely for me.
From the docs:
import { longestCommonSubstring } from 'string-algorithms';
const strings = [
'12apple',
'3apple4',
'apple56'
];
console.log(longestCommonSubstring(strings));
produces the output apple.
without DP approach
var lcs = function (n, m) {
let lcs = 0 //to store longest common substring
let s1 = n.length
let s2 = m.length
for(let i = 0;i < s1;i++){
for(let j = 0; j< s2;j++){
let track = 0
//if letter are same, do while to check next letter
if(n[i] == m[j]){
while(i + track < s1 && j + track < s2 && n[i + track] == m[j + track]){
track += 1 // to track
if (lcs < track) {
lcs += 1
}
}
}
}
}
return lcs;
};
var m = "abcdxyz"
var n = "xyzabcd" // 4
// var m = "dadef"
// var n = "adwce"//2
// var m = "acdghr";
// var n = "bgh"; //2
// var m = "A"
// var n = "A" //1
console.log(lcs(m, n));

How to collect all possible contiguous string concatenations from an array of arrays of strings?

I am trying to find an efficient way to collect all possible contiguous string concatenations from an array of arrays of strings, excluding strings with duplicated parts. Example:
var arr = [
["pq","bcd"], ["l", "ffnn", "xyz"], ["hm", "ffnn","ij"], ["ab","def","u","eeff"]
];
function f(a) {
var t = [];
a[a.length-4].forEach(function(i) {
a[a.length-3].forEach(function(j) {
if (j !== i) (
a[a.length-2].forEach(function(k) {
if (k !== j && k !== i) (
a[a.length-1].forEach(function(l) {
if (l !== k && l !== j && l !== i)
(t.push(i+","+j+","+k+","+l));
})
)
})
)
})
});
return t;
};
console.log(f(arr));
where the result will be
["pq, l, hm, ab"],
["pq, l, hm, def"],
//...and so on...
["bcd, xyz, ij, u"],
["bcd, xyz, ij, eeff"]
(Note that while, e.g., ["pq, ffnn, ffnn, ab"] is a possible combination, it is not included in the result because it contains a duplicate).
The problem is that I need to know the length of the array and write multiple nested functions correspondingly. But I need some function which will detect that length automatically, and return the desired result. Maybe it's possible to rewrite the above function using recursion, but I'm not sure if this would be the best approach to such a problem.
If I understand you correctly, given an array of array of strings n, you want a list of all possible arrays m such that
for all i, m[i] is one of n[i]
for all i and j, if i != j, m[i] != m[j]
Well, break in half.
First, consider a function combo that given an array of array of strings, produces an array of the arrays that satisfy (1). How do you write that?
combo on an empty input array produces an array containing only an empty array.
combo on a non-empty input array could work by taking the "head" (the first element of the array), and apply each string from the head in turn and prepending to every array in return value of calling combo on the "tail" (the rest of the input without the head).
Now go through that list and eliminate the entries with duplicates.
Edit: given the Tolstoivian length of some of the other suggestions, I thought I'd post my answer, which uses the Underscore library:
const flatMap = (l, f) => _.flatten(_.map(l, f), true)
const combo = a => a.length?
(v => flatMap(_.head(a), e => v.map(g => [e].concat(g))))
(combo(_.tail(a))):
[[]];
const allUniqueCombos = a => combo(a).filter(n => _.uniq(n).length == n.length)
var arr = [["pq","bcd"], ["l", "ffnn", "xyz"],
["hm", "ffnn","ij"], ["ab","def","u","eeff"]];
console.log(JSON.stringify(allUniqueCombos(arr)))
<script src="http://underscorejs.org/underscore.js"></script>
(This is far from the most efficient use of CPU -- but computers are immensely less expensive than computer programmers.)
You could use four for loops nested in each other.
I managed to get it.
It should work for n-subarrays.
Have a look and let me know if it doesn't work properly.
var arr = [["pq","bcd"], ["l", "ffnn", "xyz"], ["hm", "ffnn","ij"], ["ab","def","u","eeff"]];
var length = arr.length;
var noDuplicate = function (arr, possibleDuplicate) {
var arraySplit = arr.split(",")
for (var i = 0; i < arraySplit.length; i++) {
var arraySplitNoSpace = arraySplit[i].replace(' ', '');
if (arraySplitNoSpace === possibleDuplicate) {
return false;
}
}
return true;
};
var createLoops = function(original, adaptedOriginal, index) { // createLoops(arr, 0, 0);
var temporaryResults = [];
var temporary = adaptedOriginal ? adaptedOriginal : original[0];
for (var i = 0; i < temporary.length; i++) {
for (var j = 0; j < original[index+1].length; j++) {
if (noDuplicate(temporary[i], original[index+1][j])) {
temporaryResults.push(temporary[i] + ", " + original[index+1][j]);
};
};
};
if (index === length-2) {
var results = [];
for (var i = 0; i < temporaryResults.length; i++) {
results.push("[" + temporaryResults[i] + "]");
}
return results;
}
else {
return createLoops(original, temporaryResults, index+1);
};
};
var result = createLoops(arr, 0, 0);
console.log("result: " + result);
console.log("result.length: " + result.length);

Javascript - nested loops and indexes

I am trying to build an array that should look like this :
[
[{"name":"Mercury","index":0}],
[{"name":"Mercury","index":1},{"name":"Venus","index":1}],
[{"name":"Mercury","index":2},{"name":"Venus","index":2},{"name":"Earth","index":2}],
...
]
Each element is the concatenation of the previous and a new object, and all the indexes get updated to the latest value (e.g. Mercury's index is 0, then 1, etc.).
I have tried to build this array using the following code :
var b = [];
var buffer = [];
var names = ["Mercury","Venus","Earth"]
for (k=0;k<3;k++){
// This array is necessary because with real data there are multiple elements for each k
var a = [{"name":names[k],"index":0}];
buffer = buffer.concat(a);
// This is where the index of all the elements currently in the
// buffer (should) get(s) updated to the current k
for (n=0;n<buffer.length;n++){
buffer[n].index = k;
}
// Add the buffer to the final array
b.push(buffer);
}
console.log(b);
The final array (b) printed out to the console has the right number of objects in each element, but all the indexes everywhere are equal to the last value of k (2).
I don't understand why this is happening, and don't know how to fix it.
This is happening because every object in the inner array is actually the exact same object as the one stored in the previous outer array's entries - you're only storing references to the object, not copies. When you update the index in the object you're updating it everywhere.
To resolve this, you need to create new objects in each inner iteration, or use an object copying function such as ES6's Object.assign, jQuery's $.extend or Underscore's _.clone.
Here's a version that uses the first approach, and also uses two nested .map calls to produce both the inner (variable length) arrays and the outer array:
var names = ["Mercury","Venus","Earth"];
var b = names.map(function(_, index, a) {
return a.slice(0, index + 1).map(function(name) {
return {name: name, index: index};
});
});
or in ES6:
var names = ["Mercury","Venus","Earth"];
var b = names.map((_, index, a) => a.slice(0, index + 1).map(name => ({name, index})));
Try this:
var names = ["Mercury","Venus","Earth"];
var result = [];
for (var i=0; i<names.length; i++){
var _temp = [];
for(var j=0; j<=i; j++){
_temp.push({
name: names[j],
index:i
});
}
result.push(_temp);
}
console.log(result)
try this simple script:
var b = [];
var names = ["Mercury","Venus","Earth"];
for(var pos = 0; pos < names.length; pos++) {
var current = [];
for(var x = 0; x < pos+1; x++) {
current.push({"name": names[x], "index": pos});
}
b.push(current);
}

javascript array with numeric index without undefineds

suppose I do..
var arr = Array();
var i = 3333;
arr[i] = "something";
if you do a stringify of this array it will return a string with a whole bunch of undefined numeric entries for those entries whose index is less than 3333...
is there a way to make javascript not do this?
I know that I can use an object {} but I would rather not since I want to do array operations such as shift() etc which are not available for objects
If you create an array per the OP, it only has one member with a property name of "333" and a length of 334 because length is always set to be at least one greater than the highest index. e.g.
var a = new Array(1000);
has a length of 1000 and no members,
var a = [];
var a[999] = 'foo';
has a length of 1000 and one member with a property name of "999".
The speedy way to only get defined members is to use for..in:
function myStringifyArray(a) {
var s = [];
var re = /^\d+$/;
for (var p in a) {
if (a.hasOwnProperty(p) && re.test(p)) {
s.push(a[p]);
}
}
return '' + s;
}
Note that the members may be returned out of order. If that is an issue, you can use a for loop instead, but it will be slower for very sparse arrays:
function myStringifyArray(a) {
var s = [];
var re = /^\d+$/;
for (var i=0, iLen=a.length; i<iLen; i++) {
if (a.hasOwnProperty(i)) {
s.push(a[i]);
}
}
return '' + s;
}
In some older browsers, iterating over the array actually created the missing members, but I don't think that's in issue in modern browsers.
Please test the above thoroughly.
The literal representation of an array has to have all the items of the array, otherwise the 3334th item would not end up at index 3333.
You can replace all undefined values in the array with something else that you want to use as empty items:
for (var i = 0; i < arr.length; i++) {
if (typeof arr[i] == 'undefined') arr[i] = '';
}
Another alternative would be to build your own stringify method, that would create assignments instead of an array literal. I.e. instead of a format like this:
[0,undefined,undefined,undefined,4,undefined,6,7,undefined,9]
your method would create something like:
(function(){
var result = [];
result[0] = 0;
result[4] = 4;
result[6] = 6;
result[7] = 7;
result[9] = 9;
return result;
}())
However, a format like that is of course not compatible with JSON, if that is what you need.

JavaScript: convert objects to array of objects

I have thousands of legacy code that stores array information in a non array.
For example:
container.object1 = someobject;
container.object2 = someotherobject;
container.object3 = anotherone;
What I want to have is:
container.objects[1], container.objects[2], container.objects[3] etc.
The 'object' part of the name is constant. The number part is the position it should be in the array.
How do I do this?
Assuming that object1, object2, etc... are sequential (like an array), then you can just iterate through the container object and find all the sequential objectN properties that exist and add them to an array and stop the loop when one is missing.
container.objects = []; // init empty array
var i = 1;
while (container["object" + i]) {
container.objects.push(container["object" + i]);
i++;
}
If you want the first item object1 to be in the [1] spot instead of the more typical [0] spot in the array, then you need to put an empty object into the array's zeroth slot to start with since your example doesn't have an object0 item.
container.objects = [{}]; // init array with first item empty as an empty object
var i = 1;
while (container["object" + i]) {
container.objects.push(container["object" + i]);
i++;
}
An alternate way to do this is by using keys.
var unsorted = objectwithobjects;
var keys = Object.keys(unsorted);
var items = [];
for (var j=0; j < keys.length; j++) {
items[j] = unsorted[keys[j]];
}
You can add an if-statement to check if a key contains 'object' and only add an element to your entry in that case (if 'objectwithobjects' contains other keys you don't want).
That is pretty easy:
var c = { objects: [] };
for (var o in container) {
var n = o.match(/^object(\d+)$/);
if (n) c.objects[n[1]] = container[o];
}
Now c is your new container object, where c.object[1] == container.object1

Categories

Resources