Finding row and column of a multidimensional array in javascript - javascript

I defined an array in javascript like this:
var chessboard = [];
chessboard.push(["a1", "b1", "c1","d1","e1","f1","g1","h1"]);
chessboard.push(["a2", "b2", "c2","d2","e2", "f2","g2","h2"]);
chessboard.push(["a3", "b3", "c3","d3","e3", "f3","g3","h3"]);
chessboard.push(["a4", "b4", "c4","d4","e4", "f4","g4","h4"]);
chessboard.push(["a5", "b5", "c5","d5","e5", "f5","g5","h5"]);
chessboard.push(["a6", "b6", "c6","d6","e6", "f6","g6","h6"]);
chessboard.push(["a7", "b7", "c7","d7","e7", "f7","g7","h7"]);
chessboard.push(["a8", "b8", "c8","d8","e8", "f8","g8","h8"]);
What I'm struggling to find out is how to find the index if the element is passed.
Example: If I pass "a5" the programme should be able to tell me (row,column) as (4,0)
**CODE:**
<!DOCTYPE html>
<html>
<head>
<title>Javascript Matrix</title>
</head>
<body>
<script>
var chessboard = [];
chessboard.push(["a1", "b1", "c1","d1","e1", "f1","g1","h1"]);
chessboard.push(["a2", "b2", "c2","d2","e2", "f2","g2","h2"]);
chessboard.push(["a3", "b3", "c3","d3","e3", "f3","g3","h3"]);
chessboard.push(["a4", "b4", "c4","d4","e4", "f4","g4","h4"]);
chessboard.push(["a5", "b5", "c5","d5","e5", "f5","g5","h5"]);
chessboard.push(["a6", "b6", "c6","d6","e6", "f6","g6","h6"]);
chessboard.push(["a7", "b7", "c7","d7","e7", "f7","g7","h7"]);
chessboard.push(["a8", "b8", "c8","d8","e8", "f8","g8","h8"]);
alert(chessboard[0][1]); // b1
alert(chessboard[1][0]); // a2
alert(chessboard[3][3]); // d4
alert(chessboard[7][7]); // h8
</script>
</body>
</html>
This is where I am right now.
EDIT2:
Thank you so much everyone :) I feel very happy.
It seems there are multiple ways to it!
What I'm trying to do is this >>
Find out the (row,column) of two squares.
Example:
Square 1: a4
Square 2: c7
||x,y|| = row1-row2, column1-column2
Now find out (x,y) from another 8x8 matrix/array.
And display data from matrix(x,y).

Since it's a chessboard you can get the info from the element itself, without iterating the board:
function findCoo(el) {
return [
el[1] - 1, // the row value - 1
el[0].codePointAt() - 'a'.codePointAt() // the column ascii value - ascii value of a
];
}
console.log("a5", findCoo("a5"));
console.log("d6", findCoo("d6"));
alert("a5" + ' ' + findCoo("a5"));

For frequent use, I suggest to take an object with the positions and return just an array with the coordinates of the wanted field.
var chessboard = [["a1", "b1", "c1", "d1", "e1", "f1", "g1", "h1"], ["a2", "b2", "c2", "d2", "e2", "f2", "g2", "h2"], ["a3", "b3", "c3", "d3", "e3", "f3", "g3", "h3"], ["a4", "b4", "c4", "d4", "e4", "f4", "g4", "h4"], ["a5", "b5", "c5", "d5", "e5", "f5", "g5", "h5"], ["a6", "b6", "c6", "d6", "e6", "f6", "g6", "h6"], ["a7", "b7", "c7", "d7", "e7", "f7", "g7", "h7"], ["a8", "b8", "c8", "d8", "e8", "f8", "g8", "h8"]],
positions = Object.create(null); // empty object without prototypes
chessboard.forEach(function (a, i) {
a.forEach(function (b, j) {
positions[b] = [i, j];
});
});
console.log(positions['a5']); // [4, 0]
console.log(positions);
.as-console-wrapper { max-height: 100% !important; top: 0; }
For getting a field name, you could use Number#toString, with a radix of 36 for letters.
function getField(i, j) {
return (j + 10).toString(36) + (i + 1).toString(10);
}
console.log(getField(4, 0)); // 'a5'
.as-console-wrapper { max-height: 100% !important; top: 0; }

You can try something like this:
Logic:
Loop over all array chessBoard and iterate over every row.
Check if the value exists in the row.
If yes, return row as iterator and column as index
var chessboard = [];
chessboard.push(["a1", "b1", "c1","d1","e1","f1","g1","h1"]);
chessboard.push(["a2", "b2", "c2","d2","e2", "f2","g2","h2"]);
chessboard.push(["a3", "b3", "c3","d3","e3", "f3","g3","h3"]);
chessboard.push(["a4", "b4", "c4","d4","e4", "f4","g4","h4"]);
chessboard.push(["a5", "b5", "c5","d5","e5", "f5","g5","h5"]);
chessboard.push(["a6", "b6", "c6","d6","e6", "f6","g6","h6"]);
chessboard.push(["a7", "b7", "c7","d7","e7", "f7","g7","h7"]);
chessboard.push(["a8", "b8", "c8","d8","e8", "f8","g8","h8"]);
function findPosition(str){
for(var i = 0; i< chessboard.length; i++) {
var index = chessboard[i].indexOf(str);
if(index>=0) {
return "row: " + i + ", col: " + index;
}
}
}
console.log(findPosition('a5'));
console.log(findPosition('d5'));

Since what you're storing is a chessboard, so instead of traversing all the elements inside the array and do searching, you can add a method to chessboard and return the [row,column] by some simple calculation:
let chessboard = [["a1", "b1", "c1", "d1", "e1", "f1", "g1", "h1"], ["a2", "b2", "c2", "d2", "e2", "f2", "g2", "h2"], ["a3", "b3", "c3", "d3", "e3", "f3", "g3", "h3"], ["a4", "b4", "c4", "d4", "e4", "f4", "g4", "h4"], ["a5", "b5", "c5", "d5", "e5", "f5", "g5", "h5"], ["a6", "b6", "c6", "d6", "e6", "f6", "g6", "h6"], ["a7", "b7", "c7", "d7", "e7", "f7", "g7", "h7"], ["a8", "b8", "c8", "d8", "e8", "f8", "g8", "h8"]]
chessboard.findEl = (input) => ([input[1]-1 ,input[0].charCodeAt(0)-97])
console.log(chessboard.findEl("a5"))
console.log(chessboard.findEl("b4"))

Try this
function getElement(val){
var result;
for(var i=0;i<chessboard.length;i++){
result=chessboard[i].indexOf(val);
if(result!=-1){
result='[' + i+',' + result + ']';
break;
}
}
return result;
}
console.log(getElement("a5"));

Related

Remove objects from array comparing with another array

I have an array blackList where I store blacklisted business names, now I have a results array of objects with many business, I want to store in an array the business names which are not included in the blackListed array, what is the easier and most performant way to do this?
Is a nested loop really needed for this?
blackList = [ "Dominos Pizza", "Domino's Pizza", "McDonald's", "McDonalds", "Telepizza", "Subway", "Burger King", "KFC", "Pans&Co", "Pans&Company" ,
"Rodilla", "Rodilla Campamento", "Granier", "Llaollao" , "Taco Bell", "Wendy's", "Dunkin' Donuts", "Pizza Hut", "Papa John's Pizza", "Little Caesars",
"Panera Bread", "Chipotle", "Papa Murphy's", "Hungry Howie", "Chipotle Mexican Grill", "Starbucks"],
list = [ { name:'business 1' }, { name:'business 2' }, { name:'business 3' } ]
The easiest way to do this is to use filter and destructuring:
const blackList = ["Dominos Pizza", "Domino's Pizza", "McDonald's", "McDonalds", "Telepizza", "Subway", "Burger King", "KFC", "Pans&Co", "Pans&Company",
"Rodilla", "Rodilla Campamento", "Granier", "Llaollao", "Taco Bell", "Wendy's", "Dunkin' Donuts", "Pizza Hut", "Papa John's Pizza", "Little Caesars",
"Panera Bread", "Chipotle", "Papa Murphy's", "Hungry Howie", "Chipotle Mexican Grill", "Starbucks"
];
const list = [{
name: 'business 1'
}, {
name: 'business 2'
}, {
name: 'business 3'
}, {
name: "Granier"
}];
const notOnBlacklist = list.filter(({ name }) => !blackList.includes(name));
console.log(notOnBlacklist);
.as-console-wrapper { max-height: 100% !important; top: auto; }
Try
let blackList =
{"Dominos Pizza":1, "Domino's Pizza":1, "McDonald's":1, "McDonalds":1
,"Telepizza":1, "Subway":1, "Burger King":1, "KFC":1, "Pans&Co":1
,"Pans&Company":1, "Rodilla":1, "Rodilla Campamento":1, "Granier":1
,"Llaollao":1, "Taco Bell":1, "Wendy's":1, "Dunkin' Donuts":1, "Pizza Hut":1
,"Papa John's Pizza":1, "Little Caesars":1, "Panera Bread":1, "Chipotle":1
,"Papa Murphy's":1, "Hungry Howie":1, "Chipotle Mexican Grill":1
,"Starbucks":1 };
let list = [];
addBusiness("'business 1'");
addBusiness("Domino's Pizza");
addBusiness("'business 2'");
addBusiness("Hungry Howie");
addBusiness("'business 3'");
console.log(list);
function addBusiness (name) {
if (blackList.hasOwnProperty(name)) return;
list.push({'name':name});
}

How to generate a random name with a preceding nametag in Screeps?

In the Programming Game Screeps I spawn creeps by using:
if(transporters.length < 0 && harvesters.length > 2) {
var newName = Game.spawns['SpawnZone'].createCreep([WORK,CARRY,MOVE], undefined, {role: 'transporter'});
console.log('Spawning new Transporter: ' + newName);
}
The 'undefined' tag is to spawn the creep with a random name. Now I'm wondering since I got different types of creeps if I can add a roletag infront of it? Like, for example, [Transporter] RandomName.
Is that possible?
I found that just naming with their job and the current game time fills the need well.
ex: "Builder" + Game.time.toString() = Builder1234
A spawn can only make one creep at a time, so the name should always be unique.
Only issue is if 2+ spawners try to make a bot at the same time (same tick), whomever didn't start the spawn first will fail with with ERR_NAME_EXISTS, but you could just get them on your next cycle.
You could implement a function that will generate the name in the format you want and replace undefined with the generated name. From Screeps documentation:
createCreep(body, [name], [memory])
Start the creep spawning process. The required energy amount can be
withdrawn from all spawns and extensions in the room.
[...]
name (optional) string
The name of a new creep. It should be unique
creep name, i.e. the Game.creeps object should not contain another
creep with the same name (hash key). If not defined, a random name
will be generated.
The Screeps Forum actually already has a solution for what you need. Transcript below:
var names1 = ["Jackson", "Aiden", "Liam", "Lucas", "Noah", "Mason", "Jayden", "Ethan", "Jacob", "Jack", "Caden", "Logan", "Benjamin", "Michael", "Caleb", "Ryan", "Alexander", "Elijah", "James", "William", "Oliver", "Connor", "Matthew", "Daniel", "Luke", "Brayden", "Jayce", "Henry", "Carter", "Dylan", "Gabriel", "Joshua", "Nicholas", "Isaac", "Owen", "Nathan", "Grayson", "Eli", "Landon", "Andrew", "Max", "Samuel", "Gavin", "Wyatt", "Christian", "Hunter", "Cameron", "Evan", "Charlie", "David", "Sebastian", "Joseph", "Dominic", "Anthony", "Colton", "John", "Tyler", "Zachary", "Thomas", "Julian", "Levi", "Adam", "Isaiah", "Alex", "Aaron", "Parker", "Cooper", "Miles", "Chase", "Muhammad", "Christopher", "Blake", "Austin", "Jordan", "Leo", "Jonathan", "Adrian", "Colin", "Hudson", "Ian", "Xavier", "Camden", "Tristan", "Carson", "Jason", "Nolan", "Riley", "Lincoln", "Brody", "Bentley", "Nathaniel", "Josiah", "Declan", "Jake", "Asher", "Jeremiah", "Cole", "Mateo", "Micah", "Elliot"]
var names2 = ["Sophia", "Emma", "Olivia", "Isabella", "Mia", "Ava", "Lily", "Zoe", "Emily", "Chloe", "Layla", "Madison", "Madelyn", "Abigail", "Aubrey", "Charlotte", "Amelia", "Ella", "Kaylee", "Avery", "Aaliyah", "Hailey", "Hannah", "Addison", "Riley", "Harper", "Aria", "Arianna", "Mackenzie", "Lila", "Evelyn", "Adalyn", "Grace", "Brooklyn", "Ellie", "Anna", "Kaitlyn", "Isabelle", "Sophie", "Scarlett", "Natalie", "Leah", "Sarah", "Nora", "Mila", "Elizabeth", "Lillian", "Kylie", "Audrey", "Lucy", "Maya", "Annabelle", "Makayla", "Gabriella", "Elena", "Victoria", "Claire", "Savannah", "Peyton", "Maria", "Alaina", "Kennedy", "Stella", "Liliana", "Allison", "Samantha", "Keira", "Alyssa", "Reagan", "Molly", "Alexandra", "Violet", "Charlie", "Julia", "Sadie", "Ruby", "Eva", "Alice", "Eliana", "Taylor", "Callie", "Penelope", "Camilla", "Bailey", "Kaelyn", "Alexis", "Kayla", "Katherine", "Sydney", "Lauren", "Jasmine", "London", "Bella", "Adeline", "Caroline", "Vivian", "Juliana", "Gianna", "Skyler", "Jordyn"]
Creep.getRandomName = function(prefix){
var name, isNameTaken, tries = 0;
do {
var nameArray = Math.random() > .5 ? names1 : names2;
name = nameArray[Math.floor(Math.random() * nameArray.length)];
if (tries > 3){
name += nameArray[Math.floor(Math.random() * nameArray.length)];
}
tries++;
isNameTaken = Game.creeps[name] !== undefined;
} while (isNameTaken);
return prefix+" "+name;
}
Similar to #Matthew-Regul I just gave them a random serial number attached to their duty :
'UPGRADER_' + (Math.floor(Math.random() * 65534) + 1)
Although his removes the extremely slight possibility of repeated names
I found that the default naming scheme in screeps is lacking because the name doesn't say much about the role of creeps. For this I wrote a small utility class called util.nameBuilder.
It uses Memory.nameIndex = {}; to keep track of the number of times a prefix has been assigned to a creep. Because I don't want to randomly increase the count if the spawning of a creep failed I have a getName(role) and a commitName(role). getName() returns a name for use and commitName() will increase the count by 1. You might want to 'fold' the count if it goes above a certain threshold(say 1000) to prevent names like harvester243874. My spawn method will actually call commitName(role) if createCreep() returns a 'name already in use' error.
The result of this code are names like:
harvester1, builder23, upgrader5
var nameBuilder = {
getName: function(role) {
if (Memory.nameIndex === undefined)
Memory.nameIndex = {};
if (Memory.nameIndex[role] === undefined)
Memory.nameIndex[role] = 0;
return role + (Memory.nameIndex[role] + 1);
},
commitName: function(role) {
var newIndex = Memory.nameIndex[role] + 1;
Memory.nameIndex[role] = newIndex;
}
};
module.exports = nameBuilder;
"Upgrader_" + spawn.name + "_" + Game.time
Creates a garanteed unique name.

Get key Json and search with name var [duplicate]

This question already has answers here:
Accessing an object property with a dynamically-computed name
(19 answers)
Closed 7 years ago.
I have the following problem:
I have the following JSON:
var words = {
"categorias": [
{
"Licores": ["Smirnoff", "Johnnie Walker", "Bacardi", "Martini", "Hennessy", "Absolut", "Jack Daniels", "Chivas Regal", " Baileys", "Ballantines", "CAPTAIN MORGAN", "CUERVO", "JAEGERMEISTER", "MOET ET CHANDON", "DEWARS", "JIM BEAM", "GALLO", "HARDYS", "CROWN ROYAL", "RICARD", "CONCHA Y TORO", "GREY GOOSE", "GORDONS", "GRANTS", "JAMESON", "MALIBU", "STOLICHNAYA", "MARTELL", "HAVANA CLUB", "REMY MARTIN", "PATRON", "YELLOWTAIL", "SAUZA", "SKYY", "FINLANDIA", "BERINGER", "TANQUERAY", "DREHER", "BEEFEATER", "BOMBAY", "SEAGRAM", "CANADIAN CLUB", "GLENFIDDICH", "COINTREAU", "TEACHERS", "KAHLUA", "BELLS", "CINZANO VERMOUTH", "LINDEMANS", "COURVOISIER", "CANADIAN MIST", "TORRES", "INGLENOOK", "CASTILLO", "KUMALA", "PENFOLDS", "LANSON", "Ron", "Vodka", "Whisky", "Bourbon", "Brandy", "Cognac", "Tequila", "Ginebra", "Vino blanco", "Vino tinto", "Champagne", "Cerveza", "Budweiser", "Heineken", "Sambuca", "Frangelico", "Triple Sec", "Licor de cafe", "Kirsch", "Fernet", "Aguardiente", "Pisco", "Sangría", "Mojito", "Margarita", "Cuba libre", "Daiquiri", "Cosmopolitan", "Caipirinha", "White Russian", "Coco Loco", "Mai Tai", "Manhattan", "Zombie", "Gintonic", "Hurricane", "Negroni", "Paloma", "Farnell"]
},
{
"animales": ["Abadejo", "Abanto", "Abeja", "Abeja doméstica", "Abejorro", "Abubilla", "Abulón", "Acedía", "Acentor", "Acevia", "Acocil", "Acranio", "Actinia", "Addax", "Agachadiza", "Aguará", "Águila", "Agutí", "Ajolote", "Alacrán", "Albatros", "Alburno", "Alcaraván", "Alcatraz", "Alcaudón", "Alce", "Alcélafo", "Alimoche", "Almeja", "Alondra ibis", "Alosa", "Alpaca", "Alzacola", "Ameba", "Ampelis", "Anaconda", "Anchoa", "Anfioxo", "Angelote", "Anguila", "Aninga", "Anoa", "Anolis", "Ánsar", "Anta", "Antílope", "Araguato", "Araña", "Arapaima", "Arapapa", "Ardilla", "Arenque", "Argonauta", "Armadillo", "Armiño", "Arrendajo", "Asno", "Atún", "Avefría", "Avestruz", "Avispa", "Avetoro", "Avispón", "Avoceta", "Avutarda", "Ayeaye", "Ayu", "Babirusa", "Babosa", "Babuino", "Bacalao", "Baiji"]
}
]
}
So when I want search a Categoria I call this function:
function random(max){
return Math.floor((Math.random() * max) + 0);
}
Now as the Key of JSON is a array (categorias), and this key i want get of way random, then i use Object.keys(), and it runs smoothly, when i assigned the var namKeyJson to Object.keys(words.categorias[randomCategory]), i returned the name of the key which i need
var lengthCategory = words.categorias.length-1;
var randomCategory = random(lengthCategory);
var nameKeyJson = Object.keys(words.categorias[randomCategory]);
nameKeyJson = nameKeyJson.toString();
the problem is when i want get the values or the length the categorys of array, and that by placing the variable nameKeyJson, takes the name of the variable but not its value.
var lengthPregunta = words.categorias[randomCategory].nameKeyJson.length;
console.log(lengthPregunta);
Thanks for help me.
var lengthPregunta = words.categorias[randomCategory].nameKeyJson.length;
Should be
var lengthPregunta = words.categorias[randomCategory][nameKeyJson].length;
You try to call 'nameKeyJson' from words.categorias[randomCategory] instead of indexing key by nameKeyJson.
Use bracket notations:
words.categorias[randomCategory][nameKeyJson]
and with your code it will always return only first variable.
So change
var lengthCategory = words.categorias.length-1; to
var lengthCategory = words.categorias.length;
var words = {
"categorias": [{
"Licores": ["Smirnoff", "Johnnie Walker", "Bacardi", "Martini", "Hennessy", "Absolut", "Jack Daniels", "Chivas Regal", " Baileys", "Ballantines", "CAPTAIN MORGAN", "CUERVO", "JAEGERMEISTER", "MOET ET CHANDON", "DEWARS", "JIM BEAM", "GALLO", "HARDYS", "CROWN ROYAL", "RICARD", "CONCHA Y TORO", "GREY GOOSE", "GORDONS", "GRANTS", "JAMESON", "MALIBU", "STOLICHNAYA", "MARTELL", "HAVANA CLUB", "REMY MARTIN", "PATRON", "YELLOWTAIL", "SAUZA", "SKYY", "FINLANDIA", "BERINGER", "TANQUERAY", "DREHER", "BEEFEATER", "BOMBAY", "SEAGRAM", "CANADIAN CLUB", "GLENFIDDICH", "COINTREAU", "TEACHERS", "KAHLUA", "BELLS", "CINZANO VERMOUTH", "LINDEMANS", "COURVOISIER", "CANADIAN MIST", "TORRES", "INGLENOOK", "CASTILLO", "KUMALA", "PENFOLDS", "LANSON", "Ron", "Vodka", "Whisky", "Bourbon", "Brandy", "Cognac", "Tequila", "Ginebra", "Vino blanco", "Vino tinto", "Champagne", "Cerveza", "Budweiser", "Heineken", "Sambuca", "Frangelico", "Triple Sec", "Licor de cafe", "Kirsch", "Fernet", "Aguardiente", "Pisco", "Sangría", "Mojito", "Margarita", "Cuba libre", "Daiquiri", "Cosmopolitan", "Caipirinha", "White Russian", "Coco Loco", "Mai Tai", "Manhattan", "Zombie", "Gintonic", "Hurricane", "Negroni", "Paloma", "Farnell"]
}, {
"animales": ["Abadejo", "Abanto", "Abeja", "Abeja doméstica", "Abejorro", "Abubilla", "Abulón", "Acedía", "Acentor", "Acevia", "Acocil", "Acranio", "Actinia", "Addax", "Agachadiza", "Aguará", "Águila", "Agutí", "Ajolote", "Alacrán", "Albatros", "Alburno", "Alcaraván", "Alcatraz", "Alcaudón", "Alce", "Alcélafo", "Alimoche", "Almeja", "Alondra ibis", "Alosa", "Alpaca", "Alzacola", "Ameba", "Ampelis", "Anaconda", "Anchoa", "Anfioxo", "Angelote", "Anguila", "Aninga", "Anoa", "Anolis", "Ánsar", "Anta", "Antílope", "Araguato", "Araña", "Arapaima", "Arapapa", "Ardilla", "Arenque", "Argonauta", "Armadillo", "Armiño", "Arrendajo", "Asno", "Atún", "Avefría", "Avestruz", "Avispa", "Avetoro", "Avispón", "Avoceta", "Avutarda", "Ayeaye", "Ayu", "Babirusa", "Babosa", "Babuino", "Bacalao", "Baiji"]
}]
}
function random(max) {
return Math.floor((Math.random() * max) + 0);
}
var lengthCategory = words.categorias.length;
var randomCategory = random(lengthCategory);
var nameKeyJson = Object.keys(words.categorias[randomCategory]);
var lengthPregunta = words.categorias[randomCategory][nameKeyJson].length;
console.log(lengthPregunta);

Node js queue return elements from an array

I'm trying to implement a queue in node js.I have an array with elements and i want at every 1 sec to insert a new one.I want to return every time only two elements from queue(at every 5 seconds).I want the queue to continue returning values from where remains.An example.I have an array [1,2,3,4].At every 2 sec i insert a new elemt in array.I return 2 elements from array at every 5 sec.Does anyone know how to make this work? Here is my code:
var queue = require('queue');
var posts=["aaa","bbbb","ccc",'ddd'];
var n=posts.length;
function populateQueue(q) {
for (var i = 0; i < posts.length; i++) {
(function(index) {
q.push(function(done) {
console.log('done', posts[index]);
setTimeout(done, 5000);
posts.splice(0,2);
});
})(i);
}
}
function insert() {
posts.push({"name":haiku()});
cxc();
}
function cxc() {
populateQueue(q2);
}
setInterval(insert,2000);
var q2 = queue({concurrency: 2});
populateQueue(q2);
q2.start();
function haiku(){
var adjs = ["autumn", "hidden", "bitter", "misty", "silent", "empty", "dry",
"dark", "summer", "icy", "delicate", "quiet", "white", "cool", "spring",
"winter", "patient", "twilight", "dawn", "crimson", "wispy", "weathered",
"blue", "billowing", "broken", "cold", "damp", "falling", "frosty", "green",
"long", "late", "lingering", "bold", "little", "morning", "muddy", "old",
"red", "rough", "still", "small", "sparkling", "throbbing", "shy",
"wandering", "withered", "wild", "black", "young", "holy", "solitary",
"fragrant", "aged", "snowy", "proud", "floral", "restless", "divine",
"polished", "ancient", "purple", "lively", "nameless"]
, nouns = ["waterfall", "river", "breeze", "moon", "rain", "wind", "sea",
"morning", "snow", "lake", "sunset", "pine", "shadow", "leaf", "dawn",
"glitter", "forest", "hill", "cloud", "meadow", "sun", "glade", "bird",
"brook", "butterfly", "bush", "dew", "dust", "field", "fire", "flower",
"firefly", "feather", "grass", "haze", "mountain", "night", "pond",
"darkness", "snowflake", "silence", "sound", "sky", "shape", "surf",
"thunder", "violet", "water", "wildflower", "wave", "water", "resonance",
"sun", "wood", "dream", "cherry", "tree", "fog", "frost", "voice", "paper",
"frog", "smoke", "star"];
return adjs[Math.floor(Math.random()*(adjs.length-1))]+"_"+nouns[Math.floor(Math.random()*(nouns.length-1))];
}
I have a quick answer to this. Specifically involving your question, but not your code. You have to tell me what your code does, otherwise I can't help you with it. But to do with your question, I have this:
First, setup your initial queue and index.
let queue = [1, 2, 3, 4, 5],
index = 0;
Now you have to declare two functions, (1) The one that enqueues values in your array. In my case, I enqueue a random number
enqueue = () => {
queue.push(Math.floor(Math.random()*10));
console.log(queue);
}
The other one gets two values at the current index, and increments the index by 2, once the storing is done. The values are then, returned.
get_two_elements = () => {
let pointed_slice = queue.slice(index, index + 2);
index += 2;
console.log(pointed_slice);
return pointed_slice;
};
Finally, to make the contraption work, you have to put timeouts on them like this
setInterval(enqueue, 2000);
setInterval(get_two_elements, 5000);
Set interval is non-blocking, thus both will happen at almost the sametime with a difference ranging between nanoseconds and milliseconds. This will successfully do what your question sounds like to me.
For reference, I placed a gist on the whole code for you here:
https://gist.github.com/jekku/012eed5ea9c356f8fa29

Sort array of objects in specific order

I have an array of objects returning from an API call which I need to sort into a specific format.
I'm trying to organise the destination_country_id alphabetically except for the first three and last items. For example, like so:
"Ireland"
"United Kingdom"
"United States"
...other countries, alphabetically...
"Everywhere Else"
I have considered using array.sort(), which I understand I can easily use to sort them alphabetically, but I've so far been unsuccessful in figuring out how I can achieve the desired output.
API Response
[
{
"destination_country_id":null,
"primary_cost":"9.50",
"region_id":null,
"destination_country_name":"Everywhere Else",
},
{
"destination_country_id":105,
"primary_cost":"8.00",
"region_id":null,
"destination_country_name":"United Kingdom",
},
{
"destination_country_id":209,
"primary_cost":"9.50",
"region_id":null,
"destination_country_name":"United States",
},
{
"destination_country_id":123,
"primary_cost":"5.00",
"region_id":null,
"destination_country_name":"Ireland",
},
{
"destination_country_id":185,
"primary_cost":"5.00",
"region_id":null,
"destination_country_name":"France",
},
{
"destination_country_id":145,
"primary_cost":"5.00",
"region_id":null,
"destination_country_name":"Spain",
}
]
Possibly not the most efficient method but it is ES3, doesn't require any libraries, and is fairly easy to understand. Also assuming you wanted to sort alphabetically on destination_country_name
Javascript
// where x is your array of objects
x.sort(function (a, b) {
// sorts everything alphabetically
return a.destination_country_name.localeCompare(b.destination_country_name);
}).sort(function (a, b) {
// moves only this to country to top
return +(!b.destination_country_name.localeCompare('United States'));
}).sort(function (a, b) {
// moves only this to country to top
return +(!b.destination_country_name.localeCompare('United Kingdom'));
}).sort(function (a, b) {
// moves only this to country to top
return +(!b.destination_country_name.localeCompare('Ireland'));
}).sort(function (a, b) {
// moves only this to country to bottom
return +(!a.destination_country_name.localeCompare('Everywhere Else'));
});
console.log(JSON.stringify(x, ['destination_country_name']));
Output
[{"destination_country_name":"Ireland"},
{"destination_country_name":"United Kingdom"},
{"destination_country_name":"United States"},
{"destination_country_name":"France"},
{"destination_country_name":"Spain"},
{"destination_country_name":"Everywhere Else"}]
On jsFiddle
We could even go a step further and use the above example to make a reusable function, like.
Javascript
function sorter(array, funcs, orders) {
funcs = funcs || {};
orders = orders || {};
array.sort(funcs.general);
if (Array.isArray(orders.top)) {
orders.top.slice().reverse().forEach(function(value) {
array.sort(funcs.top.bind(value));
});
}
if (Array.isArray(orders.bottom)) {
orders.bottom.forEach(function(value) {
array.sort(funcs.bottom.bind(value));
});
}
return array;
}
sorter(x, {
general: function (a, b) {
return a.destination_country_name.localeCompare(b.destination_country_name);
},
top: function (a, b) {
return +(!b.destination_country_name.localeCompare(this));
},
bottom: function (a, b) {
return +(!a.destination_country_name.localeCompare(this));
}
}, {
top: ['Ireland', 'United Kingdom', 'United States'],
bottom: ['Everywhere Else']
});
On jsFiddle
And now you can easily sort on different attributes by parsing in different compare functions, and define values that should be at the top or bottom.
I used ECMA5 methods but you could just as easily make it with ECMA3.
I think the most efficient way to sort your array is to first find where "Everywhere Else", the "UK", "Ireland", and the "US" are in your array, remove them, and then sort the rest of the array. This is simpler than it sounds
fiddle
var data = [
{"destination_country_name": "Everywhere Else"},
{"destination_country_name": "United Kingdom"},
{"destination_country_name": "United States"},
{"destination_country_name": "Ireland"},
{"destination_country_name": "France"},
{"destination_country_name": "Spain"} ];
//removed the other elements just to make the example cleaner
var keep = ["Everywhere Else", "Ireland", "United Kingdom", "United States"];
//keep is the elements you want in the front; order them exactly at you want them ordered
var top = [];
//this is our holder array to hold the objects for the strings in keep
for (var i = 0; i < keep.length; i++) {
var index = function () {
for (var j = 0; j < data.length; j++){ //loop through data
if (data[j].destination_country_name == keep[i])
return data[j]; //return the object if it's name matches the one in keep
}
}
if (index > -1){ //if the object is in the array (index != -1)
top.push(data[index]); //push the object to our holder array
data.splice(index, 1); //splice the object out of the original array
}
}
//after this loop, those other objects will have been removed
//sort the rest of that array of objects
data.sort(function (a, b) { //use a callback function to specify which parts of
//the object need to be sorted
//basic sorting/compare algorithm (-1, 0, or 1)
if (a.destination_country_name > b.destination_country_name)
return 1; //if greater
if (a.destination_country_name < b.destination_country_name)
return -1; //if lesser
return 0; //otherwise
})
var sorted = top.concat(data), //combine data to the holder array and assign to sorted
extra = sorted.shift(); //grab the first element ("Everywhere Else") and remove it
sorted.push(extra); //add that element to the end of the array
console.log(sorted);
Alternatively, if you know those four places (EE, UK, US, and Ireland) will always be the first 4 elements in your array, you can do the following:
var data = [
{"destination_country_name": "Everywhere Else"},
{"destination_country_name": "United Kingdom"},
{"destination_country_name": "United States"},
{"destination_country_name": "Ireland"},
{"destination_country_name": "France"},
{"destination_country_name": "Spain"} ];
var top = data.slice(0,4);
data.sort(function (a, b) {
if (a.destination_country_name > b.destination_country_name)
return 1;
if (a.destination_country_name < b.destination_country_name)
return -1;
return 0;
})
var sorted = top.concat(data),
extra = sorted.shift();
sorted = sorted.push(extra); //put "Everywhere Else" at the end of the array
Note how this is much more efficient (and much simpler!) because you don't need to locate those four elements.
You can give every object a 'sort-order' property. Specify the known first 3 and the last, and give all the others the same value, greater than the first three and less than the last. Then sort the array- first by sort-order, and then alphabetically;
var arr= [{ "destination_country_id": null, "primary_cost": "9.50",
"region_id": null, "destination_country_name": "Everywhere Else",
},{ "destination_country_id": 105, "primary_cost": "8.00",
"region_id": null, "destination_country_name": "United Kingdom",
},{ "destination_country_id": 209, "primary_cost": "9.50",
"region_id": null, "destination_country_name": "United States",
},{ "destination_country_id": 123, "primary_cost": "5.00",
"region_id": null, "destination_country_name": "Ireland", },{
"destination_country_id": 185, "primary_cost": "5.00",
"region_id": null, "destination_country_name": "France", },{
"destination_country_id": 145, "primary_cost": "5.00",
"region_id": null, "destination_country_name": "Spain", }]
var s= "destination_country_name",
order= ["Ireland", "United Kingdom",
"United States", "Everywhere Else"];
arr.forEach(function(itm){
var i= order.indexOf(itm[s]);
if(i!= -1) itm.sort_order= i== 3? 1e50: i;
else itm.sort_order= 10;
});
arr.sort(function(a, b){
var d= a.sort_order- b.sort_order;
if(d===0){
if(a[s]=== b[s]) return 0;
return a[s]>b[s]? 1: -1;
}
return d;
});
JSON.stringify(arr)
/* returned value: (String)[{
"destination_country_id": 123, "primary_cost": "5.00", "region_id": null,
"destination_country_name": "Ireland", "sort_order": 0
},{
"destination_country_id": 105, "primary_cost": "8.00", "region_id": null,
"destination_country_name": "United Kingdom", "sort_order": 1
},{
"destination_country_id": 209, "primary_cost": "9.50", "region_id": null,
"destination_country_name": "United States", "sort_order": 2
},{
"destination_country_id": 185, "primary_cost": "5.00", "region_id": null,
"destination_country_name": "France", "sort_order": 10
},{
"destination_country_id": 145, "primary_cost": "5.00", "region_id": null,
"destination_country_name": "Spain", "sort_order": 10
},{
"destination_country_id": null, "primary_cost": "9.50", "region_id": null,
"destination_country_name": "Everywhere Else", "sort_order": 1e+50
}
]
*/
If your provided array is called list, you can sort it as you want using the following call:
list.sort(function (item1, item2) {
if (item1.destination_country_name < item2.destination_country_name) {
return -1;
}
return 1;
});
you can use underscore sortBy method:
a=[{obj:'first3'},{obj:'first2'},{obj:'first1'},{obj:'z'},{obj:'m'},{obj:'c'},{obj:'end3'},{obj:'end2'},{obj:'end1'}]
a=_.sortBy(a,function (t,i){if (i<=2) return String.fromCharCode(0);if(i>=a.length-3) return String.fromCharCode(255);return t.obj })
console.log(JSON.stringify(a))
[{"obj":"first3"},{"obj":"first2"},{"obj":"first1"},{"obj":"c"},{"obj":"m"},{"obj":"z"},{"obj":"end3"},{"obj":"end2"},{"obj":"end1"}]
http://jsfiddle.net/43Q8h/

Categories