Quering in a array/list in CouchDB - javascript

I do not know how to implement the following query in CouchDB:
chr.letter between two objects/dicts in chr are not the same and no X, and
the document must be in range 200000 - 2000000, but I guess it has to be done with startkey and endkey in the view.
The example output could look like this:
{"_id":"7", "sub_name":"B01", "name":"A", "pos":828288, "s_type":1}
{"_id":"8", "sub_name":"B01", "name":"A", "pos":171878, "s_type":3} will not meet range condition in the view
{"_id":"9", "sub_name":"B01", "name":"A", "pos":871963, "s_type":3}
Document 10 is not valid, because chr.no = 6 has chr.letter = X.
And document 14 is not valid, because chr.no = 5 and chr.no = 6 both have the same chr.letter = G
The database contains following documents:
{
"_id":"10",
"_rev":"3-5288068d2c4ef3e6a9d3f8ff4e3377dd",
"sub_name":"B01",
"name":"A",
"pos":1932523,
"s_type":1,
"chr":[
{
"letter":"T",
"no":4
},
{
"letter":"A",
"no":5
},
{
"letter":"X",
"no":6
}
],
"type":"Test"
}{
"_id":"14",
"_rev":"3-21300d06c31224416b8ff71b71b304d8",
"sub_name":"B01",
"name":"A",
"pos":667214,
"s_type":1,
"chr":[
{
"letter":"T",
"no":4
},
{
"letter":"G",
"no":5
},
{
"letter":"G",
"no":6
}
],
"type":"Test"
}{
"_id":"7",
"_rev":"2-1516ba547bdd21724158bc854f39f66b",
"sub_name":"B01",
"name":"A",
"pos":828288,
"s_type":1,
"chr":[
{
"letter":"C",
"no":5
},
{
"letter":"T",
"no":6
}
],
"type":"Test"
}{
"_id":"8",
"_rev":"2-750078ccc9e74616f33a2537e41b8414",
"sub_name":"B01",
"name":"A",
"pos":171878,
"s_type":3,
"chr":[
{
"letter":"C",
"no":5
},
{
"letter":"T",
"no":6
}
],
"type":"Test"
}{
"_id":"9",
"_rev":"2-3d68352a2d98c56fd322ae674fb7c38a",
"sub_name":"B01",
"name":"A",
"pos":871963,
"s_type":3,
"chr":[
{
"letter":"A",
"no":5
},
{
"letter":"G",
"no":6
}
],
"type":"Test"
}
The above database has been created with the below script:
import couchdb
# $ sudo systemctl start couchdb
# http://localhost:5984/_utils/
server = couchdb.Server()
db = server.create("test")
# except couchdb.http.ResourceConflict:
#db = server["test"]
r = [["Test", "A", "B01", 828288, 1, 7, 'C', 5],
["Test", "A", "B01", 828288, 1, 7, 'T', 6],
["Test", "A", "B01", 171878, 3, 8, 'C', 5],
["Test", "A", "B01", 171878, 3, 8, 'T', 6],
["Test", "A", "B01", 871963, 3, 9, 'A', 5],
["Test", "A", "B01", 871963, 3, 9, 'G', 6],
["Test", "A", "B01", 1932523, 1, 10, 'T', 4],
["Test", "A", "B01", 1932523, 1, 10, 'A', 5],
["Test", "A", "B01", 1932523, 1, 10, 'X', 6],
["Test", "A", "B01", 667214, 1, 14, 'T', 4],
["Test", "A", "B01", 667214, 1, 14, 'G', 5],
["Test", "A", "B01", 667214, 1, 14, 'G', 6]]
# _id = None
for i in r:
_id = str(i[5])
doc = db.get(_id)
if doc is None:
doc = {
'type': i[0],
'name': i[1],
'sub_name': i[2],
'pos': i[3],
's_type': i[4],
'_id': _id,
'chr':[]
}
doc['chr'].append({
"letter":i[6],
"no":i[7]
})
else:
doc['chr'].append({
"letter":i[6],
"no":i[7]
})
db.save(doc)
How is it possible to implement the above query or does the documents structure has to be change to make the query possible?

Solution thanks to https://stackoverflow.com/a/26436244/977828
function(doc) {
var judge = function (doc) {
var unexpect = "X";
var letter1 = unexpect, letter2 = unexpect;
for (var i in doc.chr) {
var chr = doc.chr[i];
if (chr.no == 5) {
letter1 = chr.letter;
} else if (chr.no == 6) {
letter2 = chr.letter;
}
}
if (letter1 != letter2 && letter1 != unexpect && letter2 != unexpect) {
return true;
}
return false;
};
if (judge(doc)) {
emit(doc);
}
}

Related

Calculate Percentage in Java Script and Output Result

I am trying to use below Script to Get the Average of Disconnect Devices .The results are output in group for each Test Customer .
var dataObject = [{
"Customer_Nbr": "13",
"Customer_Name": "Test1",
"Connected_Devices": 7,
"Disconnected_Devices": 1,
"Total_Devices": 8
},
{
"Customer_Nbr": "13",
"Customer_Name": "Test1",
"Connected_Devices": 6,
"Disconnected_Devices": 2,
"Total_Devices": 8
},
{
"Customer_Nbr": "12",
"Customer_Name": "Test3",
"Connected_Devices": 8,
"Disconnected_Devices": 2,
"Total_Devices": 10
}
];
groups = dataObject.reduce(function(r, o) {
var k = o.Customer_Nbr + o.Customer_Name;
if (r[k]) {
if (o.Disconnected_Devices)
(r[k].Disconnected_Devices += o.Disconnected_Devices) && ++r[k].Average;
} else {
r[k] = o;
r[k].Average = 1; // taking 'Average' attribute as an items counter(on the first phase)
}
return r;
}, {});
// getting "average of Points"
var result = Object.keys(groups).map(function(k) {
groups[k].Average = Math.round(groups[k].Disconnected_Devices / groups[k].Average);
return groups[k];
});
console.log(result)
Now I also want grouped output to have a percentage calculation which would be result/Total_Devices * 100 .
Output Should be Something like Assuming Total_Devices Count is constant in Input data -
[
{
Customer_Nbr: '13',
Customer_Name: 'Test1',
Connected_Devices: 7,
Disconnected_Devices: 3,
Total_Devices: 8,
Average: 2
Percent: 25
},
{
Customer_Nbr: '12',
Customer_Name: 'Test3',
Connected_Devices: 8,
Disconnected_Devices: 2,
Total_Devices: 10,
Average: 2
Percent: 20
}
]
Something like this maybe?
var dataObject = [
{
Customer_Nbr: "13",
Customer_Name: "Test1",
Connected_Devices: 7,
Disconnected_Devices: 1,
Total_Devices: 8,
},
{
Customer_Nbr: "13",
Customer_Name: "Test1",
Connected_Devices: 6,
Disconnected_Devices: 2,
Total_Devices: 8,
},
{
Customer_Nbr: "12",
Customer_Name: "Test3",
Connected_Devices: 8,
Disconnected_Devices: 2,
Total_Devices: 10,
},
];
groups = dataObject.reduce(function (r, o) {
var k = o.Customer_Nbr + o.Customer_Name;
if (r[k]) {
if (o.Disconnected_Devices)
(r[k].Disconnected_Devices += o.Disconnected_Devices) && ++r[k].Average;
} else {
r[k] = o;
r[k].Average = 1; // taking 'Average' attribute as an items counter(on the first phase)
}
return r;
}, {});
// getting "average of Points"
var result = Object.keys(groups).map(function (k) {
groups[k].Average = Math.round(
groups[k].Disconnected_Devices / groups[k].Average
);
groups[k].percentage = (groups[k].Average/groups[k].Total_Devices) * 100;
return groups[k];
});
console.log(result);

Group the objects in javascript

Need to check does "X" or "O" has more occurrences. The values of the array possibilities should be compared against the row value of the moves array. As we find the value of the occurrence reaches 3, we need to stop the iteration.
const possibilities = [
[0, 1, 2],
[3, 4, 5],
...
];
const moves = [{
"row": 0,
"type": "X",
},
{
"row": 1,
"type": "O",
},
{
"row": 2,
"type": "O",
},
{
"row": 3,
"type": "X",
},
{
"row": 4,
"type": "O",
},
{
"row": 5,
"type": "X",
}];
Code as follows:
let count = 0;
possibilities.forEach((possibility) => {
let type = null;
for (let index = 0; index < possibility.length; index++) {
console.log(possibility[index], "index")
for (let j = 0; j < moves; j++) {
if (moves[j].row === possibility[index]) {
console.log(moves[j], "j")
if (type === null) {
type = moves[j].type;
} else if (type === moves[j].type) {
++count;
} else {
type = null;
count = 0;
}
}
}
}
})
This code may help you.
If this did not work. Please write a comment. So I can edit my answer.
This code is not fully optimized!! But I can do that if the code works for you.
let counts = {}
for(const possibility of possibilities) {
for(const move of moves) {
if(possibility.includes(move.row)) {
if(!(move.type in counts)) counts[move.type] = 0
counts[move.type]++
}
}
}
console.log(counts)
let heightsValue = -1
let heightsType = '-'
for(const type in counts) {
if(counts[type] > heightsValue) {
heightsType = type
heightsValue = counts[type]
}
}
console.log(heightsType)
If I understand correctly, you want to iterate over possibilities to see if at least 3 of their moves are type 'X'.
Predispositions...
const possibilities = [
[0, 1, 2], // ['X', 'O', 'O'] -> false
[3, 4, 5], // ['X', 'O', 'X'] -> false
[0, 3, 5], // ['X', 'X', 'X'] -> true
];
const moves = [{
"row": 0,
"type": "X",
}, {
"row": 1,
"type": "O",
}, {
"row": 2,
"type": "O",
}, {
"row": 3,
"type": "X",
}, {
"row": 4,
"type": "O",
}, {
"row": 5,
"type": "X",
}];
match moves
let result = possibilities.map((possibility) =>
possibility.map((row) => moves.find(r => r.row === row).type)
);
// [ [ 'X', 'O', 'O' ], [ 'X', 'O', 'X' ], [ 'X', 'X', 'X' ] ]
find out how many Xs
result = result.map((posibility) =>
posibility.filter(moveType => moveType === 'X').length
);
// [1, 2, 3]
compare there at at least 3 Xs
result = result.map((xMoves) => xMoves >= 3);
// [false, false, true]
All in one
let result = possibilities.map((possibility) =>
possibility.map((row) => moves.find(r => r.row === row).type)
.filter(moveType => moveType === 'X')
.length >= 3
);
// [false, false, true]
The 3rd values in possibilities (possibilities[2] is the winner)

How to concat sub array in typescript or javascript?

How to concat sub array in typescript or javascript? In may case I want concat all values with same name.
My array is
[
{
name: "AAA"
values: [[1573054321, 0], [1573054560, 0]]
}, {
name: "BBB"
values: [[1573054388, 0], [1573054596, 0]]
}
], [
{
name: "AAA"
values: [[1573054355, 0], [1573054542, 0]]
}, {
name: "BBB"
values: [[1573054325, 0], [1573054545, 0]]
}
]
I want this in my output:
[
{
name: "AAA"
values: [[1573054321, 0], [1573054560, 0], [1573054355, 0], [1573054542, 0]]
}, {
name: "BBB"
values: [[1573054388, 0], [1573054596, 0], [1573054325, 0], [1573054545, 0]]
}
]
My typescript exemple with a simple concat (allMetricSeries is my input):
let metricSeries: MetricSeries[] = [];
allMetricSeries.forEach(metrics => {
metricSeries = metricSeries.concat(metrics);
});
You can use a simple loop with a new array to accomplish this.
let array = [
[{
name: "AAA",
values: [[1573054321, 0], [1573054560, 0]]
},
{
name: "BBB",
values: [[1573054388, 0], [1573054596, 0]]
}],
[{
name: "AAA",
values: [[1573054355, 0], [1573054542, 0]]
},
{
name: "BBB",
values: [[1573054325, 0], [1573054545, 0]]
}]
];
let output = {};
// we loop every array
array.forEach((subArray) => {
// we loop every array of array
subArray.forEach((data) => {
// if the key does not exists, we create it.
if(!output.hasOwnProperty(data.name)) {
output[data.name] = {
name: data.name,
values: []
};
}
// push the value.
output[data.name].values = output[data.name].values.concat(data.values);
})
});
// we returns only the values of our object.
console.log(Object.values(output));
One way would be to first build a dictionary of the form name => values, and then building our target array from that dictionary (by generating an object of the form {name: values} from each entry in the dictionary)
//your initial array
var arr = [[
{
name: "AAA",
values: [[1573054321, 0], [1573054560, 0]]
}, {
name: "BBB",
values: [[1573054388, 0], [1573054596, 0]]
}
], [
{
name: "AAA",
values: [[1573054355, 0], [1573054542, 0]]
}, {
name: "BBB",
values: [[1573054325, 0], [1573054545, 0]]
}
]];
//temporary dictionary to help us build the new array
//of the form {'AAA' => [values], 'BBB' => [values]}
var dict = {};
for(var sub of arr) {
for(var x of sub) {
if(dict[x.name]) {
dict[x.name] = dict[x.name].concat(x.values);
}
else {
dict[x.name] = x.values;
}
}
}
//now building the new array from the dictionary:
var new_arr = [];
for (key in dict) {
new_arr.push({name:key, values:dict[key]});
}
console.log(new_arr);
One way of doing it.
resultObj = {};
[[
{
name: "AAA",
values: [[1573054321, 0], [1573054560, 0]]
}, {
name: "BBB",
values: [[1573054388, 0], [1573054596, 0]]
}
], [
{
name: "AAA",
values: [[1573054355, 0], [1573054542, 0]]
}, {
name: "BBB",
values: [[1573054325, 0], [1573054545, 0]]
}
]].forEach((subArray) => {
subArray.forEach((arr) => {
const name = arr.name;
if (!resultObj[name]) {
resultObj[name] = arr.values.slice();
} else {
resultObj[name].push(...arr.values);
}
});
});
finalResult = Object.keys(resultObj).map((key) => {
return {name: key, values: resultObj[key]}
});
Another way through reduce method and spread operator:
let data = [
[
{
name: "AAA",
values: [[1573054321, 0], [1573054560, 0]]
}, {
name: "BBB",
values: [[1573054388, 0], [1573054596, 0]]
}
],
[
{
name: "AAA",
values: [[1573054355, 0], [1573054542, 0]]
}, {
name: "BBB",
values: [[1573054325, 0], [1573054545, 0]]
}
]
];
const result = data.reduce((a, c) => {
let innerResult = c.reduce((ia, ic) => {
ia[ic.name] = ia[ic.name] || {name: ic.name, values:[]};
ia[ic.name].values.push(ic.values);
return ia;
}, {});
for (const key in innerResult) {
a[key] = a[key] || {values: []};
a[key].values.push(...innerResult[key].values);
}
return a;
}, {});
console.log(result);

sheetjs xlsx, How to write merged cells?

I need to create a xlsx with merged cells using sheetjs.
data:
[
{
"id": "nick",
"items": [
{
"name": "ball"
},
{
"name": "phone"
}
]
},
{
"id": "jack",
"items": [
{
"name": "pen"
},
{
"name": "doll"
}
]
}
]
My code:
var ws = XLSX.utils.json_to_sheet(data);
var wb = XLSX.utils.book_new();
XLSX.utils.book_append_sheet(wb, ws, "");
var wbout = XLSX.write(wb, {bookType:'xlsx', type:'array'});
saveAs(new Blob([wbout],{type:"application/octet-stream"}), filename + ".xlsx");
The result I want to get:
How do I get this result?
... Thank you
const merge = [
{ s: { r: 1, c: 0 }, e: { r: 2, c: 0 } },{ s: { r: 3, c: 0 }, e: { r: 4, c: 0 } },
];
ws["!merges"] = merge;
Use this code for merge A2:A3 ({ s: { r: 1, c: 0 }, e: { r: 2, c: 0 } })
and A4:A5 ({ s: { r: 3, c: 0 }, e: { r: 4, c: 0 } })
Here s = start, r = row, c=col, e= end

Transforming JSON based on inputs and outputs

Following is an object array that has a value v, its input i and output o.
var data = [
{
v: 1,
i: [],
o: [1, 2, 3]
},
{
v: 2,
i: [2],
o: [4, 5, 6]
]
},
{
v: 3,
i: [1, 4],
o: [7, 8]
},
{
v: 4,
i: [],
o: [3]
}
]
The final JSON structure is created by checking the input and outputs of each v, i.e. the parent child relations...
Final JSON structure..
[
{
v: 1,
children: [
{
v: 2
},
{
v: 3
}
]
},
{
v: 4
}
]
I tried by the following code, but it's not transforming the object array properly...
function checkForOutputs(outputs, groupedValueChainEntityLists) {
for (var i = 0; i < outputs.length; i++) {
for (var j = 0; j < groupedValueChainEntityLists[j].inputs.length; j++) {
var val_Chain = groupedValueChainEntityLists[j].inputs.map((item) => {
if (outputs[i].o === item.o) {
return groupedValueChainEntityLists[j];
}
});
return val_Chain;
}
}
}
function constructValueChainRelations(data) {
var valueChainArray = new Array();
var result = data.map((item) => {
if (item.i.length === 0) {
valueChainArray.push(item);
return checkForOutputs(item.o, data);
}
});
console.log(result);
}
I think that you are making this too difficult. Simply map the values.
var data = [{
v: 1,
i: [],
o: [1, 2, 3]
}, {
v: 2,
i: [2],
o: [4, 5, 6]
}, {
v: 3,
i: [1, 4],
o: [7, 8]
}, {
v: 4,
i: [],
o: [3]
}];
function transform(verticies, idProp, childProp) {
return verticies.map(function(vertex) {
return {
v: vertex[idProp],
children: vertex[childProp].filter(function(childVertex) {
return childVertex !== vertex[idProp];
}).map(function(childVertex) {
return {
v: childVertex
};
})
}
});
}
var transformed = transform(data, 'v', 'o');
document.body.innerHTML = '<pre>' + JSON.stringify(transformed, null, 4) + '</pre>';
Result
[{
"v": 1,
"children": [{
"v": 2
}, {
"v": 3
}]
}, {
"v": 2,
"children": [{
"v": 4
}, {
"v": 5
}, {
"v": 6
}]
}, {
"v": 3,
"children": [{
"v": 7
}, {
"v": 8
}]
}, {
"v": 4,
"children": [{
"v": 3
}]
}]
You could use some loops and a look up mechanism with this.
var data = [{ v: 1, i: [], o: [1, 2, 3] }, { v: 2, i: [2], o: [4, 5, 6] }, { v: 3, i: [1, 4], o: [7, 8] }, { v: 4, i: [], o: [3] }],
result = [];
data.forEach(function (a) {
if (!this[a.v]) {
this[a.v] = { v: a.v, children: [] };
result.push(this[a.v]);
}
a.o.forEach(function (b) {
var k = a.v + '|' + b;
if (a.v !== b && !this[k]) {
this[k] = { v: b };
this[a.v].children.push(this[k]);
}
}, this);
}, {});
document.write('<pre>' + JSON.stringify(result, 0, 4) + '</pre>');
Here's another way that is working..
Sample Code
function populateChildrenRecursively(outputTypeId, valueChainEntities, parentValueChainEntity) {
for (var i = 0; i < valueChainEntities.length; i++) {
if (valueChainEntities[i].valueChainEntity.valueChainEntityId != parentValueChainEntity.valueChainEntity.valueChainEntityId && hasInput(outputTypeId, valueChainEntities[i].inputs)) {
parentValueChainEntity.valueChainEntity.items.push(valueChainEntities[i]);
if (valueChainEntities[i].outputs.length > 0) {
valueChainEntities[i].valueChainEntity.items = [];
for (var j = 0; j < valueChainEntities[i].outputs.length; j++) {
populateChildrenRecursively(valueChainEntities[i].outputs[j].outputTypeId, valueChainEntities, valueChainEntities[i]);
}
}
}
}
}
JSON Conversion

Categories

Resources