Whenever I open a PDF-file in Illustrator for edithing, there are a lot of ungrouped and uncategorized Elemetns in it.
So I tried to select multiple elements with a spicific name with the below Script, but since the name of the elements are between Angle-brackets "<someName>" script wont select them:
function selectPageItemsByName(items, name) {
for (var i = 0; i < items.length; i++) {
var item = items[i];
if (item.name === name) {
item.selected = true;
}
}
}
function main() {
var document = app.activeDocument;
var name = '<someFile>';
document.selection = null;
selectPageItemsByName(document.pageItems, name);
}
main();
Femkeblanko from Adobe Community says: Items with angle brackets in their label (unless user-created) are unnamed. They correspond to an empty string, i.e. "".
If I remove the Brackets from the name of the Elemetns, the script works but I have a lot of Elements and it needs time.
So, isn't there a way to salve it?
this is a pretty creative way:
// Select->Objects->Clipping Mask
app.executeMenuCommand("Clipping Masks menu item");
// Edit->Clear
app.executeMenuCommand("clear");
but it isn't really documented very well
some links for future reference:
Where is the perfect reference of adobe illustrator script?
https://ai-scripting.docsforadobe.dev/index.html
https://ten-artai.com/illustrator-ccver-22-menu-commands-list/
https://github.com/ten-A/AiMenuObject
I have multiple for loops in one code, as I am trying to collect data based off identifier "Y". There are some sheets that do not have identifier "Y" and those sheets always cause my script to stop running as the error cannot find the length in that specific for loop since there is none.
How do I get around this? I've tried if/else in everywhere I think would work and it's not working.
I've tried if/else statements and breaks but I must not be putting them in the right spot.
var VDSLr = VDSL.getRange('A:AS');
var VDSLraw = VDSLr.getValues();
var VDSLdata = []
for (var i = 0; i< VDSLraw.length ; i++){
if (VDSLraw[i][44] == "Y")
{
VDSLdata.push(VDSLraw[i])
}
Pull.getRange(Pull.getLastRow()+1,1, VDSLdata.length,
VDSLdata[0].length).setValues(VDSLdata);
}
var ITr = IT.getRange('A:AS');
var ITrawdata = ITr.getValues();
var ITd= []
for (var i = 0; i< ITrawdata.length ; i++){
if(ITrawdata[i][44] == "Y")
{
ITd.push(ITrawdata[i])
}
Pull.getRange(Pull.getLastRow()+1,1, ITd.length,
ITd[0].length).setValues(ITd);
}
**Edit: it won't let me post a picture of my error yet. Here's a few
examples though:
Error (1):**
var VDSLr = VDSL.getRange('A:AS');
var VDSLraw = VDSLr.getValues();
var VDSLdata = []
for (var i = 0; i< VDSLraw.length ; i++){
if (VDSLraw[i][44] != "Y")**continue**;
if (VDSLraw[i][44] == "Y");
{
VDSLdata.push(VDSLraw[i])
}
}
Pull.getRange(Pull.getLastRow()+1,1, VDSLdata.length,
VDSLdata[0].length).setValues(VDSLdata);
var ITr = IT.getRange('A:AS');
var ITrawdata = ITr.getValues();
var ITd= []
for (var i = 0; i< ITrawdata.length ; i++){
if (ITrawdata[i][44] != "Y")continue;
if (ITrawdata[i][44] == "Y")
{
ITd.push(ITrawdata[i])
}
}
Pull.getRange(Pull.getLastRow()+1,1, ITd.length,
ITd[0].length).setValues(ITd);
So if I put a continue here, it won't read the length. Error code is "Cannot read property "length" from undefined. Which I know is correct. This is what I'm trying to bypass. "VDSL" is a sheet that normally does not have what I am looking for. But since it won't find the length it won't continue to sheet "IT."
I have also moved around the continues to different spots, and even a break (in the same spot as continue) but my combinations seem to provide a never ending loop of the same info.
The other attempt is with if else statements. When I use those I get a synthax error. On this error(2) I've tried:
if (VDSLraw[i][44] == "Y")
{//code here}
else if (VDSLraw[i][44] != "Y"){break};
I feel like I'm making this more complicated than it is, should be a simple if/then statement but since I have to pull the data and compile it to one sheet the for loop is the best way to go. Just can't figure out the last piece. I could do them separately but that's my last resort. There's 12 sheets, so clicking 12 scripts each time I need to do this doesn't seem efficient.
as soon as you provided limited information about your data I made some assumptions, I hope it matches your needs.
function getY_Data(){
// get the current Spreadsheet;
var currentSpreadsheet = SpreadsheetApp.getActiveSpreadsheet();
// get all tabs on the file, so you wont need to keep track of how many tabs you have
var tabsArray = currentSpreadsheet.getSheets();
var resultsSheet = currentSpreadsheet.getSheetByName("results");
var currentSheetValues;
var collected_Y_Rows = [];
// iterate over all tabs
tabsArray.forEach(function(tabObject,index){
// skip the results tab
if(tabObject.getName() === "results"){ continue; }
// set the current sheet data to currentSheetValues variable
currentSheetValues = tabsArray[0].getDataRange().getValues();
// Im considering that all your sheets has the same row size
currentSheetValues.forEach(function(row,index){
if(row[44] == "Y"){
collected_Y_Rows.push(row);
}
});
});
// if it hasnt find any row with "Y" it won't clear the "results" tab or try do add empty data to the "results" sheet
if(collected_Y_Rows.length === 0){
return;
}
// clear the current values and formats
resultsSheet.clear();
// append new data starting on row 1 and col 2;
// Im considering that all your sheets has the same row size;
// if the sheets tabs has different sizes of data (columns) it will throw an error because when using the range.setValues(collected_Y_Rows),
// all rows on "collected_Y_Rows" mas have the same size;
resultsSheet.getRange(1, 1, collected_Y_Rows.length, collected_Y_Rows[0].length).setValues(collected_Y_Rows);
}
first question ever here...
I am coding a simple 3-card poker hand evaluator and am having problems finding/extracting multiple "straights" (sequential series of values) from an array of values.
I need to extract and return EVERY straight the array possibly has. Here's an example:
(assume array is first sorted numerically incrementing)
myArray = [1h,2h,3c,3h,4c]
Possible three-value sequences are:
[1h,2h,3c]
[1h,2h,3h]
[2h,3c,4c]
[2h,3h,4c]
Here is my original code to find sequences of 3, where the array contains card objects with .value and .suit. For simplicity in this question I just put "2h" etc here:
private var _pokerHand = [1h,2h,3c,3h,4c];
private function getAllStraights(): Array
{
var foundStraights:Array = new Array();
for (var i: int = 0; i < (_handLength - 2); i++)
{
if ((_pokerHand[i].value - _pokerHand[i + 1].value) == 1 && (_pokerHand[i + 1].value - _pokerHand[i + 2].value) == 1)
{
trace("found a straight!");
foundStraights.push(new Array(_pokerHand[i], _pokerHand[i + 1], _pokerHand[i + 2]));
}
}
return foundStraights;
}
but it of course fails when there are value duplicates (like the 3's above). I cannot discard duplicates because they could be of different suits. I need every possible straight as in the example above. This allows me to run the straights through a "Flush" function to find "straight flush".
What array iteration technique am I missing?
This is an interesting problem. Given the popularity of poker games (and Flash) I'm sure this has been solved many times before, but I couldn't find an example online. Here's how I would approach it:
Look at it like a path finding problem.
Begin with every card in the hand as the start of a possible path (straight).
While there are possible straights:
Remove one from the list.
Find all the next valid steps, (could be none, or up to 4 following cards with the same value), and for each next valid step:
If it reaches the goal (completes a straight) add it to a list of found straights.
Otherwise add the possible straight with the next step back to the stack.
This seems to do what you want (Card object has .value as int):
private function getAllStraights(cards:Vector.<Card>, straightLength:uint = 3):Vector.<Vector.<Card>> {
var foundStraights:Vector.<Vector.<Card>> = new <Vector.<Card>>[];
var possibleStraights:Vector.<Vector.<Card>> = new <Vector.<Card>>[];
for each (var startingCard:Card in cards) {
possibleStraights.push(new <Card>[startingCard]);
}
while (possibleStraights.length) {
var possibleStraight:Vector.<Card> = possibleStraights.shift();
var lastCard:Card = possibleStraight[possibleStraight.length - 1];
var possibleNextCards:Vector.<Card> = new <Card>[];
for (var i:int = cards.indexOf(lastCard) + 1; i < cards.length; i++) {
var nextCard:Card = cards[i];
if (nextCard.value == lastCard.value)
continue;
if (nextCard.value == lastCard.value + 1)
possibleNextCards.push(nextCard);
else
break;
}
for each (var possibleNextCard:Card in possibleNextCards) {
var possibleNextStraight:Vector.<Card> = possibleStraight.slice().concat(new <Card>[possibleNextCard]);
if (possibleNextStraight.length == straightLength)
foundStraights.push(possibleNextStraight);
else
possibleStraights.push(possibleNextStraight);
}
}
return foundStraights;
}
Given [1♥,2♥,3♣,3♥,4♣] you get: [1♥,2♥,3♣], [1♥,2♥,3♥], [2♥,3♣,4♣], [2♥,3♥,4♣]
It gets really interesting when you have a lot of duplicates, like [1♥,1♣,1♦,1♠,2♥,2♣,3♦,3♠,4♣,4♦,4♥]. This gives you:
[1♥,2♥,3♦], [1♥,2♥,3♠], [1♥,2♣,3♦], [1♥,2♣,3♠], [1♣,2♥,3♦], [1♣,2♥,3♠], [1♣,2♣,3♦], [1♣,2♣,3♠], [1♦,2♥,3♦], [1♦,2♥,3♠], [1♦,2♣,3♦], [1♦,2♣,3♠], [1♠,2♥,3♦], [1♠,2♥,3♠], [1♠,2♣,3♦], [1♠,2♣,3♠], [2♥,3♦,4♣], [2♥,3♦,4♦], [2♥,3♦,4♥], [2♥,3♠,4♣], [2♥,3♠,4♦], [2♥,3♠,4♥], [2♣,3♦,4♣], [2♣,3♦,4♦], [2♣,3♦,4♥], [2♣,3♠,4♣], [2♣,3♠,4♦], [2♣,3♠,4♥]
I haven't checked this thoroughly but it looks right at a glance.
I'm collecting rows of answers from a database which are made in to arrays. Something like:
for (var i:int = 0; i < event.result.length; i++) {
var data = event.result[i];
var answer:Array = new Array(data["question_id"], data["focus_id"], data["attempts"], data["category"], data["answer"], data["correct"], data["score"]);
trace("answer: " + answer);
restoreAnswer(answer, i);
}
Now, if I trace answer, I typically get something like:
answer: 5,0,2,IK,1.a,3.1,0
answer: 5,0,1,IK,2.a,3.1,0
answer: 4,1,1,AK,3,3,2
From this we see that focus_id 0 (second array item) in question_id 5 (first array item) has been attempted twice (third array item), and I only want to use the last attempt in my restoreAnswer function.
My problem is that first attempt answers override the second attempts since the first are parsed last it seems. How do I go about only calling my restoreAnswer only when appropriate?
The options are:
1 attempts, correct score (2 points)
2 attempts, correct score (1 points)
1 attempt, wrong score (0 points)
2 attemps, wrong score (0 points)
There can be multiple focus_id in each question_id.
Thank you very much! :)
I would consider having the DB query return only the most recent attempt, or if that doesn't work efficiently, return the data in attempt order. You may score question 5 twice, but at least it'll score correctly on the last pass.
You can also filter or sort the data you get back from the server.
Michael Brewer-Davis suggested using the database query to resolve this; normally speaking, this would be the right solution.
If you wait until you get it back from the web method call or whatever in AS3, then consider creating an additional Vector variable:
var vAttempts:Vector.<Vector.<int>> = new Vector.<Vector.<int>>(this.m_iNumQuestions);
You mentioned that it seems that everything is sorted so that earlier attempts come last. First you want to make sure that's true. If so, then before you do any call to restoreAnswer(), you'll want to check vAttempts to make sure that you have not already called restoreAnswer() for that question_id and focus_id:
if (!vAttempts[data["question_id"]])
{
vAttempts[data["question_id"]] = new Vector.<int>(); // ensuring a second dimension
}
if (vAttempts[data["question_id"]].indexOf(data["focus_id"]) == -1)
{
restoreAnswer(answer, i);
vAttempts[data["question_id"]].push(data["focus_id"]);
}
So optimizing this just a little bit, what you'll have is as follows:
private final function resultHandler(event:ResultEvent):void {
var vAttempts:Vector.<Vector.<int>> = new Vector.<Vector.<int>>(this.m_iNumQuestions);
var result:Object = event.result;
var iLength:int = result.length;
for (var i:int = 0; i < iLength; i++) {
var data = result[i];
var iQuestionID:int = data["question_id"];
var iFocusID:int = data["focus_id"];
var answer:Array = [iQuestionID, iFocusID, data["attempts"],
data["category"], data["answer"], data["correct"], data["score"]];
trace("answer: " + answer);
var vFocusIDs:Vector.<int> = vAttempts[iQuestionID];
if (!vFocusIDs) {
vAttempts[iQuestionID] = new <int>[iFocusID];
restoreAnswer(answer, i);
} else if (vFocusIDs.indexOf(iFocusID) == -1) {
restoreAnswer(answer, i);
vFocusIDs.push(iFocusID);
}
}
}
Note: In AS3, Arrays can skip over certain indexes, but Vectors can't. So if your program doesn't already have some sort of foreknowledge as to the number of questions, you'll need to change vAttempts from a Vector to an Array. Also account for whether question IDs are 0-indexed (as this question assumes) or 1-indexed.
I have a store and an array. I want to remove records from the store if that record's value matches with values in the array. Following is is the code I am trying but it's not working. Can anyone suggest the correct way?
'store' is the actual store and 'filterItems' is the array of records I want to remove from 'store'.
store.each(function (record) {
for (var i = 0; i < filterItems.length; i++) {
if (record.get('ItemId') === _filterItems[i].get('ItemId')) {
itemIndex = store.data.indexOf(record);
store.removeAt(itemIndex );
}
}
});
Not sure about your code because i dont know all variables. Though its recommended to use the store.getRange() fn and iterate the array via for loop. Its better for performance.
var storeItems = store.getRange(),
i = 0;
for(; i<storeItems.length; i++){
if(Ext.Array.contains(filterItemIds, storeItems[i].get('id')))
store.remove(store.getById(storeItems[i].get('id')));
}
Here is an example which i tried right now and it works well.
https://fiddle.sencha.com/#fiddle/8r2
Try using the remove method of the store (docs)
store.remove(filterItems);
var indexes = [], i = 0;
dataviewStore.each(function(item, index){
if(item) {
if(item.data.columnId == columnId) {
indexes[i++] = index;
}
}
}, this);
dataviewStore.remove(indexes);
this is my example if your record is matches with the value then store the index of that item after storing indexes of all the items and remove them.
Otherwise you have to use for loop and remove them from end of the array.