find number of string matches from array to array in javascript? - javascript

I need to find number of strings in array b that contains in array arr. I got the output but i need it in this order.[[3,6,0],[1,3,1]]
here my code goes.
var arr = [["00","00","00","01","01","01","01","01","01"],["000","100","01","01","01"]];
var b = ["00","01",10];
var cc = [];
for (var i=0;i<b.length;i++) {
var k = [];
for (var y=0;y<arr.length;y++) {
var a = 0;
for (var x=0;x<arr[y].length;x++) {
if ((arr[y][x].substring(0,2)).indexOf(b[i]) != -1) {
a++;
}
}
k.push(a)
}
cc.push(k);
}
console.log(JSON.stringify(cc));// output :[[3,1],[6,3],[0,1]]
Actual output : [[3,1],[6,3],[0,1]]
Expected output : [[3,6,0],[1,3,1]]
I want the result either in javascript or jquery.

As you have in b number 10 you need convert it to String and then search in array, because arr contains only strings
var arr = [
["00","00","00","01","01","01","01","01","01"],
["000","100","01","01","01"]
];
var b = ["00", "01", 10];
var len, i, j, key, result = [], counts = [], count = 0;
for (i = 0, len = arr.length; i < len; i++) {
for (j = 0; j < b.length; j++) {
count = 0;
key = String(b[j]);
count = arr[i].filter(function (el) {
return el.slice(0, 2) === key;
}).length;
counts.push(count);
}
result.push(counts);
counts = [];
}
console.log(JSON.stringify(result));
Version for IE < 9, where there is not .filter method
var arr = [
["00","00","00","01","01","01","01","01","01"],
["000","100","01","01","01"]
];
var b = ["00", "01", 10];
var len,
key,
result = [],
counts = [],
i, j, k, count;
for (i = 0, len = arr.length; i < len; i++) {
for (j = 0; j < b.length; j++) {
count = 0;
key = String(b[j]);
for (k = 0; k < arr[i].length; k++) {
if (arr[i][k].slice(0, 2) === key) {
count++;
}
}
counts.push(count);
}
result.push(counts);
counts = [];
}
console.log(JSON.stringify(result));

Seems like there are some typo in your sample input. Following code may help.
var arr = [["00","00","00","01","01","01","01","01","01"],["00","10","01","01","01"]];
var b = ["00","01","10"];
var cc = [];
arr.forEach(function(ar,i){
cc[i] = [];
b.forEach(function(a,j){
cc[i][j] = ar.filter(function(d){ return d==a }).length;
});
});
alert(JSON.stringify(cc));
Or
var arr = [
["00", "00", "00", "01", "01", "01", "01", "01", "01"],
["00", "10", "01", "01", "01"]
];
var b = ["00", "01", "10"];
var cc = arr.map(function(ar) {
return b.map(function(a) {
return ar.filter(function(d) {
return d == a
}).length;
})
});
alert(JSON.stringify(cc));

Related

JavaScript Change elements in line and print them in different lines

I have this code to find the matching names and change them to others.
But they change every time and in the same line.
var names1 = ["Rui", "Jose", "Carlos", "Miguel"];
var names2 = ["Rui", "Tiago", "Jose", "Carlos", "Rogerio"];
for (var i = 0; i < names1.length; i++) {
for (var j = 0; j < names2.length; j++) {
if (names1[i] == names2[j]) {
names2[j] = "Maria", "Fred";
}
}
}
console.log(names2);
I want to know how to print them in different lines.
Because it shows like this:
MariaFred
Tiago
MariaFred
MariaFred
Rogerio
And I wanted:
maria,
Fred,
Tiago,
Rogerio.
Can you help me?
You could use an array for the excahnge names and an index for inserting a changed name if a matched name is found.
var names1 = ["Rui", "Jose", "Carlos", "Miguel"],
names2 = ["Rui", "Tiago", "Jose", "Carlos", "Rogerio"],
matched = ["Maria", "Fred"],
index = 0,
i, j;
outer: for (j = 0; j < names2.length; j++) {
for (i = 0; i < names1.length; i++) {
if (names1[i] == names2[j]) {
names2[j] = matched[index++];
index %= matched.length;
continue outer;
}
}
}
console.log(names2);
To speed up the check, you could use a hash table and check against it.
var names1 = ["Rui", "Jose", "Carlos", "Miguel"],
names2 = ["Rui", "Tiago", "Jose", "Carlos", "Rogerio"],
matched = ["Maria", "Fred"],
index = 0,
hash = Object.create(null);
names1.forEach(function (a) {
hash[a] = true;
});
names2.forEach(function (a, i, aa) {
if (hash[a]) {
aa[i] = matched[index++];
index %= matched.length;
}
});
console.log(names2);
instead of
console.log(names2)
try this
for (var i = 0; i < names2.length; i++) {
console.log(names2[i]);
}
Try this:
var names1 = ["Rui", "Jose", "Carlos", "Miguel"];
var names2 = ["Rui", "Tiago", "Jose", "Carlos", "Rogerio"];
var matchFound = false;
for (var i = 0; i < names1.length; i++) {
for (var j = 0; j < names2.length; j++) {
if (names1[i] == names2[j] && matchFound === false) {
// when the name matches, print Maria and Fred in 2 different lines
console.log("Maria,");
console.log("Fred,");
matchFound = true;
} else { // if name doesn't match, just print the element from 2nd array
console.log(names2[j]");
}
}
}
IN the following example, I think the random names should be chosen from some source
var names1 = ["Rui", "Jose", "Carlos", "Miguel"];
var names2 = ["Rui", "Tiago", "Jose", "Carlos", "Rogerio"];
var random_names = ['Maria', 'Fred', 'Someother']
var random_names_counter = 0;
for (var i = 0; i < names1.length; i++) {
for (var j = 0; j < names2.length; j++) {
if (names1[i] == names2[j]) {
names2[j] = random_names[random_names_counter++];
}
}
}
console.log(names2);

Javascript - count and remove from an object

I have an object with duplicate values and I want to count all those which have the same value and remove them.
var myArray = [{nr: 'bbc',}, {nr: 'bbc'}, {nr: 'bbc'}, {nr: ccc}];
from this array I want to create another array but remove the duplicated values and count them to be like this.
var myArray = [{nr: 'bbc',amount: 3}}, {nr: ccc,amount: 1}];
You could probably use a better format
var count = {};
for(var i = 0; i < myArray.length; ++i) {
if(typeof count[myArray[i].nr] == 'undefined') {
count[myArray[i].nr] = 0;
}
++count[myArray[i].nr];
}
and this wound yield somehing like:
count = {
bcc: 3,
ccc: 1
};
if you still need it with the structure you specified, then:
var newArray = [];
for(var k in count) {
newArray.push({
nr: k,
amount: count[k]
});
}
If you want the same structure, this will work for you
var newArray = [];
for (var i = 0; i < myArray.length; i++) {
var matched = false;
for (var j = 0; j < newArray.length; j++) {
if(myArray[i].nr === newArray[j].nr){
matched = true;
newArray[j].amount++;
break;
}
};
if(!matched)
newArray.push({nr:myArray[i].nr,amount:1});
};
console.log(newArray);

Compare javascript array of array by distinct values

Following code i wanted to share which compares two array of array:-
var x = [["x", "r", "t"], ["a", "b", "n"], ["j", "l", "x"]];
var y = [["y", "w", "z"], ["a", "b", "n"], ["j", "l", "x"]];
var objX = [];
var objY = [];
for (var i = 0; i < x.length; i++)
{
objX[i] = {};
for (var j = 0; j < x[i].length; j++)
{
objX[i][x[i][j]] = i;
}
}
for (var i = 0; i < y.length; i++)
{
objY[i] = {};
for (var j = 0; j < y[i].length; j++)
{
objY[i][y[i][j]] = i;
}
}
Object.size = function(obj) {
var size = 0, key;
for (key in obj) {
if (obj.hasOwnProperty(key))
size++;
}
return size;
};
function compareObjs(oA, oB)
{
if (Object.size(oA) > Object.size(oB))
{
aa = oA;
ba = oB;
}
else
{
aa = oB;
ba = oA;
}
for (var property in aa) {
if (!ba.hasOwnProperty(property)) {
return false;
}
}
return true;
}
function compareArrayOfObj(aA, aB)
{
var aIb = [];
var aMb = [];
var bMa = [];
var aIIndex = [];
var bIIndex = [];
var aIF = [];
var bIF = [];
if (aA.length > aB.length)
{
a = aA;
b = aB;
}
else
{
a = aB;
b = aA;
}
for (var i in a)
{
for (var j in b)
{
if (compareObjs(a[i], b[j]))
{
for (var blah in a[i])
{
aIb.push(x[a[i][blah]]);
break;
}
aIIndex.push(i);
bIIndex.push(j);
}
}
}
for (var i in a)
{
if (aIIndex.indexOf(i) == -1)
{
for (var blah in a[i])
{
aIF.push(x[a[i][blah]]);
break;
}
}
}
for (var j in b)
{
if (bIIndex.indexOf(j) == -1)
{
for (var blah in b[j])
{
bIF.push(y[b[j][blah]]);
break;
}
}
}
return {"aIb": aIb, "aMb": aIF, "bMa": bIF}
}
resultSet=compareArrayOfObj(objX, objY);
/*
resultSet object holds three properties as:-
1. aIb = objX Intersection objY
2. aMb = objX - objY
3. bMa = objY - objX
*/
Improvisation in the code is always welcome.
Basically i have written this code to have set operation on arrays.
It will return A minus B,B minus A and A intersection B.

Sort Objects in Array by Multiple Properties

I am new to js and trying to sort an array of objects by two fields - starting with the first property, and then by the second property. Both properties are numbers.
The data is:
var homes = [{
"h_id": "3",
"minimumorder": "12",
"price": "17"
}, {
"h_id": "4",
"minimumorder": "1",
"price": "20"
}, {
"h_id": "5",
"minimumorder": "1",
"price": "18.10"
}
There are more objects in the array, this is a simplified example. The below code ALMOST gets me there, but for the minimumorder property it puts 12 after 1 instead of after 6:
cmp = function(a, b) {
parseFloat(a);
parseFloat(b);
if (a > b) return +1;
if (a < b) return -1;
return 0;
}
homes.sort(function(a, b) {
return cmp(a.minimumorder,b.minimumorder) || cmp(a.price,b.price)
})
jsFiddle here.
Any help would be HUGELY appreciated, as I've been googling and tinkering for hours trying to figure this out.
You need to reassign the parsed value back to a and b:
a = parseFloat(a);
b = parseFloat(b);
Otherwise it ends up comparing strings, and 12 occurs after 1 lexically, just like the word at comes after a in the dictionary.
Updated fiddle.
Well,
You should use a code like this:
function sortHomes(homes)
{
var temp_homes = new Array();
var new_homes = new Array();
for(var i = 0; i < homes.length; i++) temp_homes[i] = homes[i];
var maximum = 0, minimum;
for(i = 0; i < temp_homes.length; i++) maximum = Math.max(maximum, temp_homes.minimumorder);
var min_price, j, k, indexes, price_indexes;
for(i = 0; i < temp_homes.length; i++){
minimum = maximum;
for(j = 0; j < temp_homes.length; j++){
minimum = Math.min(minimum, temp_homes[j].minimumorder);
}
indexes = getIndexes(temp_homes, minimum, "minimumorder");
if(indexes.length == 1){
new_homes.push(temp_homes[indexes[0]]);
temp_homes[indexes[0]].minimumorder = maximum + 1;
}
else{
for(j = 0; j < indexes.length; j++){
min_price = maximum;
for(k = 0; k < indexes.length; k++){
min_price = Math.min(min_price, temp_homes[indexes[k]].price);
}
price_indexes = getIndexes(temp_homes, min_price, "price");
for(k = 0; k < price_indexes.length; k++){
new_homes.push(temp_homes[price_indexes[k]]);
temp_homes[price_indexes[k]].price = maximum + 1;
}
}
}
}
}
function getIndexes(arr, el, name)
{
var indexes = new Array();
for(var i = 0; i < arr.length; i++) if(arr[i][name] == el) indexes.push(i);
return indexes;
}
It should work.
If it doesn't, please inform me about it.
Oh, and in order to sort homes, just use:
homes = sortHomes(homes);

How to merging javascript arrays and order by position?

Is there anyway to merge arrays in javascript by ordering by index/position. I'm try to accomplish this and haven't been able to find any examples of this.
var array1 = [1,2,3,4]
var array2 = [a,b,c,d]
var array3 = [!,#,#,$]
var merged array = [1,a,!,2,b,#,3,c,#,4,d,$]
I know you can use concat() to put one after the other.
As long as the arrays are all the same length you could just do:
var mergedArray = [];
for (var i = 0, il = array1.length; i < il; i++) {
mergedArray.push(array1[i]);
mergedArray.push(array2[i]);
mergedArray.push(array3[i]);
}
EDIT:
For arrays of varying lengths you could do:
var mergedArray = [];
for (var i = 0, il = Math.max(array1.length, array2.length, array3.length);
i < il; i++) {
if (array1[i]) { mergedArray.push(array1[i]); }
if (array2[i]) { mergedArray.push(array2[i]); }
if (array3[i]) { mergedArray.push(array3[i]); }
}
This should work for arrays of ANY length:
var mergeArrays = function () {
var arr = [],
args = arr.slice.call(arguments),
length = 0;
for (var i = 0, len = args.length; i < len; i++) {
length = args[i].length > length ? args[i].length : length;
}
for (i = 0; i < length; i++) {
for (var j = 0; j < len; j++) {
var value = args[j][i];
if (value) {
arr.push(value);
}
}
}
return arr;
};
Example:
var array1 = [1,2,3,4];
var array2 = ['a','b','c','d','e','f','g','h','i','j','k','l'];
var array3 = ['!','#','#','$','%','^','&','*','('];
mergeArrays(array1, array2, array3);
// outputs: [1, "a", "!", 2, "b", "#", 3, "c", "#", 4, "d", "$", "e", "%", "f", "^", "g", "&", "h", "*", "i", "(", "j", "k", "l"]
This would work also (a little more terse syntax):
var mergeArrays = function () {
var arr = [],
args = arr.slice.call(arguments),
length = Math.max.apply(null, args.map(function (a) { return a.length; }));
for (i = 0; i < length; i++) {
for (var j = 0, len = args.length; j < len; j++) {
var value = args[j][i];
if (value) {
arr.push(value);
}
}
}
return arr;
};
For arrays that are all the same size, where you pass one or more arrays as parameters to merge:
function merge()
{
var result = [];
for (var i=0; i<arguments[0].length; i++)
{
for (var j=0; j<arguments.length; j++)
{
result.push(arguments[j][i]);
}
}
return result;
}
var array1 = ['1','2','3','4'];
var array2 = ['a','b','c','d'];
var array3 = ['!','#','#','$'];
var merged = merge(array1, array2, array3);
Nothing built in, but it wouldn't be hard to manage:
var maxLength = Math.max(array1.length, array2.length, array3.length),
output = [];
for (var i = 0; i < maxLength; i++) {
if (array1[i] != undefined) output.push(array1[i]);
if (array2[i] != undefined) output.push(array2[i]);
if (array3[i] != undefined) output.push(array3[i]);
}
try this...
var masterList = new Array();
var array1 = [1,2,3,4];
var array2 = [a,b,c,d];
var array3 = [!,#,#,$];
for(i = 0; i < array1.length; i++) {
masterList.push(array1[i]);
masterList.push(array2[i]);
masterList.push(array3[i]);
}
It looks like you want to "zip" some number of same-length arrays into a single array:
var zip = function() {
var numArrays=arguments.length
, len=arguments[0].length
, arr=[], i, j;
for (i=0; i<len; i++) {
for (j=0; j<numArrays; j++) {
arr.push(arguments[j][i]);
}
}
return arr;
};
zip([1,2], ['a', 'b']); // => [1, 'a', 2, 'b']
zip([1,2,3], ['a','b','c'], ['!','#','#']); // => [1,'a','#',...,3,'c','#']
If the input arrays could be of different length then you've got to figure out how to deal with that case...
Yes, there is some way to do that. Just:
loop through the larger array,
until at the currently processed position both arrays have elements, assign them one-by-one to the new array,
after the shorter array ends, assign only elements from the longer array,
The resulting array will have the elements ordered by the index from the original arrays. From your decision depends, position in which one of these arrays will have higher priority.
This works for any number of array and with arrays of any length.
function myMerge() {
var result = [],
maxLength = 0;
for (var i = 0; i < arguments.length; i++) {
if (arguments[i].length > maxLength) { maxLength = arguments[i].length; }
}
for (var i = 0; i < maxLength; i++) {
for (var j = 0; j < arguments.length; j++) {
if (arguments[j].length > i) {
result.push(arguments[j][i]);
}
}
}
return result;
}
Eli beat me to the punch up there.
var posConcat = function() {
var arrays = Array.prototype.slice.call(arguments, 0),
newArray = [];
while(arrays.some(notEmpty)) {
for(var i = 0; i < arrays.length; i++) {
if(arguments[i].length > 0)
newArray.push(arguments[i].shift());
}
}
return newArray;
},
notEmpty = function() { return arguments[0].length > 0; };
Usage:
var orderedArray = posConcat(array1,array2,array3);
Sample: http://jsfiddle.net/HH9SR/

Categories