I have an array in JavaScript that have defined these values:
var myStringArray = ["1","2","3","4","5","6","7","8","9","10"];
And when I call a function the first time function, I need to get this:
1
2
3
Calling it again I need to get:
4
5
6
Calling it again:
7
8
9
Calling it again:
10
1
2
Calling again:
3
4
5
And so on. You got the point, showing 3 values from the array and if we are at the end of array, read from the beginning... I have an app that has remote control and has down and up keys. When the user presses the down button to get these values from an array as described in the above example, if the user presses the up button it needs to go back from an example...so reading the array in a loop (at end, the array is read from the beginning, but always shows three values).
I try using this:
var myStringArray = ["1","2","3","4","5","6","7","8","9","10"];
var arrayLength = myStringArray.length;
for (var i = 0; i < arrayLength; i++) {
if (i<(6)) {
console.log(myStringArray[i]);
}
}
But the next time I call this code, it shows from the beginning values of the array, not continue to read others value...do I need a second counter?
If you are OK with manipulating your original array as you loop through it you could splice and concat similar to below (or you could use a clone of the array if you need to persist the original array):
var myStringArray = ["1","2","3","4","5","6","7","8","9","10"];
var loopByX = function(x){
var y = myStringArray.splice(0,x);
myStringArray = myStringArray.concat(y);
return y;
}
console.log(loopByX(3));
console.log(loopByX(3));
console.log(loopByX(3));
console.log(loopByX(3));
console.log(loopByX(3));
If you want to go bi-directional (is that what you call it?), as mentioned in the comments, you could do it as below which then gives you the ability to go backwards or forward and the flexibility to do so in an arbitrary number:
var myStringArray = ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10"];
var loopByX = function(x) {
var len = myStringArray.length;
// Ensure x is always valid but you can add any behaviour here in that case yourself. As an example I return an empty array.
if (Math.abs(x) > len) {
return [];
}
var y = x > 0 ? myStringArray.splice(0, x) : myStringArray.splice(len + x, len);
myStringArray = x > 0 ? myStringArray.concat(y) : y.concat(myStringArray);
return y;
}
console.log(loopByX(20)); // invalid number
console.log(loopByX(-20)); // invalid number
console.log(loopByX(-3));
console.log(loopByX(-6));
console.log(loopByX(3));
console.log(loopByX(4));
You could take a function which slices three elements and if not possible, it takes the needed first values of the array as well.
function take3() {
var temp = array.slice(index, index += 3)
index %= array.length;
console.log(temp.concat(temp.length < 3 ? array.slice(0, index) : []).join(' '));
}
var array = ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10"],
index = 0;
<button onclick="take3()">take 3</button>
With a mapping of a dynamic count.
function take(length) {
console.log(Array.from({ length }, _ => array[++index, index %= array.length]));
}
var array = ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10"],
index = -1;
<button onclick="take(3)">take 3</button>
Your variable i is local to the for loop which means it basically resets every time the loop is started. So first make your variable i global.
var i=0;
function employeeNames(){
var empList = ["1","2","3","4","5","6","7","8","9","10"];
var output = [];
var j=0;
while(j<3)
{
output.push(empList[i])
i=(i+1)%empList.length;
j++;
}
return output;
}
console.log(employeeNames());
console.log(employeeNames());
console.log(employeeNames());
console.log(employeeNames());
console.log(employeeNames());
If you want the immutable way to achieve your circular looping
function loopArray(arr, step=3) {
let i = 0;
return function inner() {
for (let j = 0; j < step; j++) {
console.log(arr[i]);
i = (i + 1) % arr.length;
}
};
}
const func = loopArray(["1","2","3","4","5","6","7","8","9","10"], 3);
func();
func();
func();
func();
func();
The fancy solution with generator functions:
function* cycle(arr) {
let i=0;
while (true) {
yield arr[i++];
i %= arr.length;
}
}
function* chunksOf(n, iterable) {
let chunk = [];
for (const x of iterable) {
chunk.push(x)
if (chunk.length >= n) {
yield chunk;
chunk = [];
}
}
if (chunk.length > 0)
yield chunk;
}
function toFunction(iterator) {
return () => iterator.next().value;
}
var myStringArray = ["1","2","3","4","5","6","7","8","9","10"];
const f = toFunction(chunksOf(3, cycle(myStringArray)));
console.log(f());
console.log(f());
console.log(f());
// …
#Igor Petev, JavaScript's closures are a nice concept that you can use to solve your problem.
Please read JavaScript's Closures - w3schools article. It's really nice and excellent.
I have used the concept of closures to solve this problem. Please leave a comment if you don't understand my code or anything else related to this problem.
Please have a look at the below code.
var get3items = (function () {
var index = 0;
var myStringArray = ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10"];
var len = myStringArray.length
return function () {
for(var count = 0; count < 3; count += 1)
{
console.log(myStringArray[index]);
if(index == (len - 1))
{
index = 0;
}
else {
index += 1;
}
}
}
})();
get3items (); // First call
console.log()
get3items (); // Second call
console.log()
get3items (); // Third call
console.log()
get3items (); // Fourth call
console.log()
get3items (); // Fifth call
/*
1
2
3
4
5
6
7
8
9
10
1
2
3
4
5
*/
How about using a generator:
function* get3() {
var myStringArray = ["1","2","3","4","5","6","7","8","9","10"];
var index = 0;
while (true) {
yield [0, 1, 2].map(i => myStringArray[(index + i) % myStringArray.length])
index = (index + 3) % myStringArray.length;
}
}
Calling this function returns an object which you can call .next() on, to get the next set of 3:
var getter = get3();
console.log(getter.next().value); // ["1","2","3"]
console.log(getter.next().value); // ["4","5","6"]
console.log(getter.next().value); // ["7","8","9"]
// etc.
function* employeeNames(){
var empList = ["1","2","3","4","5","6","7","8","9","10"];
for(var i =0; i<=empList.length; i++){
yield empList[i];
}
}
var emp;
emp = employeeNames();
It uses a generator function...
Related
I am trying to find the first 100 items in a very large array that match a condition and I'd prefer to end the loop once I've found those 100 for efficiency sake, since the method for matching the items is expensive.
The problem is that doing:
const results = largeArray.filter(item => checkItemValidity(item)).slice(0, 100);
will find all the results in the large array before returning the first 100, which is too wasteful for me.
And doing this:
const results = largeArray.slice(0, 100).filter(item => checkItemValidity(item));
could return less than 100 results.
Please what's the most efficient way of doing this?
Rather than putting a conditional and break inside a for loop, just add the extra length check in the for condition itself
const data = ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14"],
isValid = n => !(n%2),
res = [],
max = 5;
for (let i = 0; i < data.length && res.length < max; i++) {
isValid(data[i]) && res.push(data[i]);
}
console.log(res)
There are several array methods that will exit early Array.some, Array.every, Array.find, Array.findIndex
You can use them to stop the iteration when you need.
Example using Array.find
const data = [-1,-6,-6,-6,1,-2,2,3,4,-5,5,6,7,-8,8,9,-10,10,11,-1,2,3,4,5,-6,7,8,-9,10,11,];
const first10 = [];
data.find(item => (item > 0 && first10.push(item), first10.length >= 10));
console.log(first10 +"");
You ocul take a generator function and exit of the wanted length is found.
function* getFirst(array, fn, n) {
let i = 0;
while (i < array.length) {
if (fn(array[i])) {
yield array[i];
if (!--n) return;
}
i++;
}
}
const
expFn = x => x % 2 === 0,
array = [2, 4, 5, 1, 3, 7, 9, 10, 6, 0];
console.log(...getFirst(array, expFn, 4));
The most efficient way would be to use a for construct instead of a function and then break out when you have reached your limit.
const results = []
for (const item of largeArray) {
// End the loop
if(results.length === 100) break
// Add items to the results
checkItemValidity(item) && results.push(item)
}
console.log(results)
You can use something like this. I.e. Finding the first 5 odd numbers
var data = ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14"]
var filterData = [];
for (let i = 0; i < data.length; i++) {
if (data[i] % 2 === 0) {
filterData.push(data[i]);
}
// Track count console.log(i)
if (filterData.length === 5)
break;
}
console.log(filterData)
You would need to do a standard "for" loop as filter function returns a new array of the given array so here is how I would approach this:
let largeArray = ["foo", "bar", "foo", "bar"]
let validateArray = ["foo"]
let newArray = []
for (let item of largeArray){
//change number to how many items needed
if (newArray.length === 2){
console.log(newArray)
// Output would be ["foo", "foo"]
break;
}
// If you have a custom function to return true or false replace here
if (validateArray.includes(item)){
newArray.push(item);
}
}
If you are not returning strings you might need to create a custom function to return true or false depending on how you would define a validate data
I'll recommend you use findIndex, the problem with the some and every is that if the array is empty it will return true
Reference: Why does Array.prototype.every return true on an empty array?
I'm going to assume that what is expensive is the function that you are using to filter items in the array, not the actual iteration.
In that case, I would recommend using the array objects .reduce() method. Inside the function you pass to it, you can check whether your accumulator is already large enough. If it isn't, then you can conditionally add to it.
const results = largeArray.reduce(( accumulator , item )=> {
if (accumulator.length <= 100) {
if (checkItemValidity(item)) {
accumulator.push(item)
}
}
return accumulator
}, [])
This question already has answers here:
Cartesian product of multiple arrays in JavaScript
(35 answers)
Closed 1 year ago.
I'm having trouble coming up with code to generate combinations from n number of arrays with m number of elements in them, in JavaScript. I've seen similar questions about this for other languages, but the answers incorporate syntactic or library magic that I'm unsure how to translate.
Consider this data:
[[0,1], [0,1,2,3], [0,1,2]]
3 arrays, with a different number of elements in them. What I want to do is get all combinations by combining an item from each array.
For example:
0,0,0 // item 0 from array 0, item 0 from array 1, item 0 from array 2
0,0,1
0,0,2
0,1,0
0,1,1
0,1,2
0,2,0
0,2,1
0,2,2
And so on.
If the number of arrays were fixed, it would be easy to make a hard coded implementation. But the number of arrays may vary:
[[0,1], [0,1]]
[[0,1,3,4], [0,1], [0], [0,1]]
Any help would be much appreciated.
Here is a quite simple and short one using a recursive helper function:
function cartesian(...args) {
var r = [], max = args.length-1;
function helper(arr, i) {
for (var j=0, l=args[i].length; j<l; j++) {
var a = arr.slice(0); // clone arr
a.push(args[i][j]);
if (i==max)
r.push(a);
else
helper(a, i+1);
}
}
helper([], 0);
return r;
}
Usage:
cartesian([0,1], [0,1,2,3], [0,1,2]);
To make the function take an array of arrays, just change the signature to function cartesian(args) instead of using rest parameter syntax.
I suggest a simple recursive generator function:
// JS
function* cartesianIterator(head, ...tail) {
const remainder = tail.length ? cartesianIterator(...tail) : [[]];
for (let r of remainder) for (let h of head) yield [h, ...r];
}
// get values:
const cartesian = items => [...cartesianIterator(items)];
console.log(cartesian(input));
// TS
function* cartesianIterator<T>(items: T[][]): Generator<T[]> {
const remainder = items.length > 1 ? cartesianIterator(items.slice(1)) : [[]];
for (let r of remainder) for (let h of items.at(0)!) yield [h, ...r];
}
// get values:
const cartesian = <T>(items: T[][]) => [...cartesianIterator(items)];
console.log(cartesian(input));
You could take an iterative approach by building sub arrays.
var parts = [[0, 1], [0, 1, 2, 3], [0, 1, 2]],
result = parts.reduce((a, b) => a.reduce((r, v) => r.concat(b.map(w => [].concat(v, w))), []));
console.log(result.map(a => a.join(', ')));
.as-console-wrapper { max-height: 100% !important; top: 0; }
After doing a little research I discovered a previous related question:
Finding All Combinations of JavaScript array values
I've adapted some of the code from there so that it returns an array of arrays containing all of the permutations:
function(arraysToCombine) {
var divisors = [];
for (var i = arraysToCombine.length - 1; i >= 0; i--) {
divisors[i] = divisors[i + 1] ? divisors[i + 1] * arraysToCombine[i + 1].length : 1;
}
function getPermutation(n, arraysToCombine) {
var result = [],
curArray;
for (var i = 0; i < arraysToCombine.length; i++) {
curArray = arraysToCombine[i];
result.push(curArray[Math.floor(n / divisors[i]) % curArray.length]);
}
return result;
}
var numPerms = arraysToCombine[0].length;
for(var i = 1; i < arraysToCombine.length; i++) {
numPerms *= arraysToCombine[i].length;
}
var combinations = [];
for(var i = 0; i < numPerms; i++) {
combinations.push(getPermutation(i, arraysToCombine));
}
return combinations;
}
I've put a working copy at http://jsfiddle.net/7EakX/ that takes the array you gave earlier ([[0,1], [0,1,2,3], [0,1,2]]) and outputs the result to the browser console.
const charSet = [["A", "B"],["C", "D", "E"],["F", "G", "H", "I"]];
console.log(charSet.reduce((a,b)=>a.flatMap(x=>b.map(y=>x+y)),['']))
Just for fun, here's a more functional variant of the solution in my first answer:
function cartesian() {
var r = [], args = Array.from(arguments);
args.reduceRight(function(cont, factor, i) {
return function(arr) {
for (var j=0, l=factor.length; j<l; j++) {
var a = arr.slice(); // clone arr
a[i] = factor[j];
cont(a);
}
};
}, Array.prototype.push.bind(r))(new Array(args.length));
return r;
}
Alternative, for full speed we can dynamically compile our own loops:
function cartesian() {
return (cartesian.cache[arguments.length] || cartesian.compile(arguments.length)).apply(null, arguments);
}
cartesian.cache = [];
cartesian.compile = function compile(n) {
var args = [],
indent = "",
up = "",
down = "";
for (var i=0; i<n; i++) {
var arr = "$"+String.fromCharCode(97+i),
ind = String.fromCharCode(105+i);
args.push(arr);
up += indent+"for (var "+ind+"=0, l"+arr+"="+arr+".length; "+ind+"<l"+arr+"; "+ind+"++) {\n";
down = indent+"}\n"+down;
indent += " ";
up += indent+"arr["+i+"] = "+arr+"["+ind+"];\n";
}
var body = "var res=[],\n arr=[];\n"+up+indent+"res.push(arr.slice());\n"+down+"return res;";
return cartesian.cache[n] = new Function(args, body);
}
var f = function(arr){
if(typeof arr !== 'object'){
return false;
}
arr = arr.filter(function(elem){ return (elem !== null); }); // remove empty elements - make sure length is correct
var len = arr.length;
var nextPerm = function(){ // increase the counter(s)
var i = 0;
while(i < len)
{
arr[i].counter++;
if(arr[i].counter >= arr[i].length){
arr[i].counter = 0;
i++;
}else{
return false;
}
}
return true;
};
var getPerm = function(){ // get the current permutation
var perm_arr = [];
for(var i = 0; i < len; i++)
{
perm_arr.push(arr[i][arr[i].counter]);
}
return perm_arr;
};
var new_arr = [];
for(var i = 0; i < len; i++) // set up a counter property inside the arrays
{
arr[i].counter = 0;
}
while(true)
{
new_arr.push(getPerm()); // add current permutation to the new array
if(nextPerm() === true){ // get next permutation, if returns true, we got them all
break;
}
}
return new_arr;
};
Here's another way of doing it. I treat the indices of all of the arrays like a number whose digits are all different bases (like time and dates), using the length of the array as the radix.
So, using your first set of data, the first digit is base 2, the second is base 4, and the third is base 3. The counter starts 000, then goes 001, 002, then 010. The digits correspond to indices in the arrays, and since order is preserved, this is no problem.
I have a fiddle with it working here: http://jsfiddle.net/Rykus0/DS9Ea/1/
and here is the code:
// Arbitrary base x number class
var BaseX = function(initRadix){
this.radix = initRadix ? initRadix : 1;
this.value = 0;
this.increment = function(){
return( (this.value = (this.value + 1) % this.radix) === 0);
}
}
function combinations(input){
var output = [], // Array containing the resulting combinations
counters = [], // Array of counters corresponding to our input arrays
remainder = false, // Did adding one cause the previous digit to rollover?
temp; // Holds one combination to be pushed into the output array
// Initialize the counters
for( var i = input.length-1; i >= 0; i-- ){
counters.unshift(new BaseX(input[i].length));
}
// Get all possible combinations
// Loop through until the first counter rolls over
while( !remainder ){
temp = []; // Reset the temporary value collection array
remainder = true; // Always increment the last array counter
// Process each of the arrays
for( i = input.length-1; i >= 0; i-- ){
temp.unshift(input[i][counters[i].value]); // Add this array's value to the result
// If the counter to the right rolled over, increment this one.
if( remainder ){
remainder = counters[i].increment();
}
}
output.push(temp); // Collect the results.
}
return output;
}
// Input is an array of arrays
console.log(combinations([[0,1], [0,1,2,3], [0,1,2]]));
You can use a recursive function to get all combinations
const charSet = [["A", "B"],["C", "D", "E"],["F", "G", "H", "I"]];
let loopOver = (arr, str = '', final = []) => {
if (arr.length > 1) {
arr[0].forEach(v => loopOver(arr.slice(1), str + v, final))
} else {
arr[0].forEach(v => final.push(str + v))
}
return final
}
console.log(loopOver(charSet))
This code can still be shorten using ternary but i prefer the first version for readability 😊
const charSet = [["A", "B"],["C", "D", "E"],["F", "G", "H", "I"]];
let loopOver = (arr, str = '') => arr[0].map(v => arr.length > 1 ? loopOver(arr.slice(1), str + v) : str + v).flat()
console.log(loopOver(charSet))
Another implementation with ES6 recursive style
Array.prototype.cartesian = function(a,...as){
return a ? this.reduce((p,c) => (p.push(...a.cartesian(...as).map(e => as.length ? [c,...e] : [c,e])),p),[])
: this;
};
console.log(JSON.stringify([0,1].cartesian([0,1,2,3], [[0],[1],[2]])));
I need to split an array into N number of arrays based on searching for an element from another array.
consider this scenerio
var test = ["1","2","3","env","6","7","8","uat","2344","wersdf","sdfs"];
var test2=["env","uat"];
now I want a map like
{
env:["6","7","8"],
uat:["2344","wersdf","sdfs"]
}
Note that the array items in test2 and test1 is dynamic.But two test2 values will not be coming one after another in the test array, there will be some items between it.
You could do with Array#Reduce
First iterate the test2 array and match the index of test
Then use the forloop with starting value ind+1 .it will target the next argument of delimiter
After pass the value to array using acc[b].push()
Then detect next delimiter using test2.indexOf(test[i]) == -1 on else condition.That time you need to break the statement.Then again start the second argument of test2
function maper(test, test2) {
return test2.reduce((acc, b) => {
let ind = test.indexOf(b); //detect starting index of delimiter
if (ind > -1) {
acc[b] = acc[b] || [];
for (var i = ind+1; i < test.length; i++) {
if (test2.indexOf(test[i]) == -1) { //detet next delimiter reach
acc[b].push(test[i])
}else{
break;
}
}
}
return acc
}, {})
}
var test = ["1", "2", "3", "env", "6", "7", "8", "uat", "2344", "wersdf", "sdfs"];
var test2 = ["env", "uat"];
console.log(maper(test, test2))
var test = ["1","2","3","env","6","7","8","uat","2344","wersdf","sdfs"];
var test2=["env","uat"];
var indexArray = [];
test2.map(key=>{
var index = test.indexOf(key);
indexArray.push(index);
})
var obj = {};
for(var i = 0; i<indexArray.length; i++){
var part = test.slice(indexArray[i]+1, indexArray[i+1]);
obj = {...obj,[test2[i]]: [ ...part]};
}
console.log("obj = ", obj);
I would like to create a simple tally system to record the data-id from the elements that are selected and combine the data-id values at the end to generate a result.
function myAnswer() {
document.getElementById('btnNxt').removeAttribute('disabled');
var myResult = '';
var iId = this.getAttribute('data-id');
myObj[page].mySel = iId;
myQueRep[page] = iId;
console.log(iId);
for (var x = 0; x < btn.length; x++) {
if (iId == x) {
btn[x].classList.add('selAnswer');
} else {
btn[x].classList.remove('selAnswer');
}
}
}
In this section, the iId variable gets the data-id value but I'm not sure how to tally the selections up and display a result based on that score.
JSFiddle of current code:
https://jsfiddle.net/mkykmg15/2/
You should be doing something with your myQueRep.
So something like:
var myQueRep = ["1", "1", "1", "2", "2", "2"]
var tally = myQueRep.reduce( function (acc, curr) {
return acc + +curr
}, 0);
console.log(tally)
I have got a fruits array as shown below
var fruits = [
{
"buyprice": "10",
"sellprice": "11",
"name": "pomogranate"
},
{
"buyprice": "10",
"sellprice": "11",
"name": "apple"
},
{
"buyprice": "12",
"sellprice": "13",
"name": "orange"
},
{
"buyprice": "14",
"sellprice": "15",
"name": "apple"
}
]
I want to find out the total counts of apple present in the array
and the buy price and sellprice of the first element of the apple present in the array (not the last element)
I have tried it this way
function findnumberofaccourences(fruits, apple) {
var a = 0;
var buyprice;
var sellprice
for (var i = 0; i < fruits.length; i++) {
var name = fruits[i].name;
buyprice = fruits[i].buyprice;
sellprice = fruits[i].sellprice;
if (name == apple) {
a++;
}
}
var p = { count: a, buyprice: buyprice, sellprice: sellprice };
return p;
}
var result = findnumberofaccourences(fruits, 'apple');
alert(JSON.stringify(result));
But when i run this i am getting the result as (the buyprice and sellprice of apple's last element , where as i need apples first element )
{"count":2,"buyprice":"14","sellprice":"15"}
This is my fiddle
http://jsfiddle.net/thkc0fpk/2/
could you please elt em know how to achive this
A few things:
As Hacketo said, only grab the prices when a == 0.
Also, only grab the price for apples, rather than all fruit.
Calling the argument giving the fruit name to find apple is a bit misleading (since it could contain the string pear). Perhaps fruitName or similar instead?
Here's a minimal-changes example:
function findnumberofaccourences(fruits, fruitName) {
var a = 0;
var buyprice;
var sellprice;
for (var i = 0; i < fruits.length; i++) {
var name = fruits[i].name;
if (name == fruitName) { // Only apples
if (a == 0) { // Only the first
buyprice = fruits[i].buyprice;
sellprice = fruits[i].sellprice;
}
a++;
}
}
var p = {
count: a,
buyprice: buyprice,
sellprice: sellprice
};
return p;
}
var result = findnumberofaccourences(fruits, 'apple');
alert(JSON.stringify(result));
You can also simplify a fair bit, using the more-modern forEach and using the object you're going to return directly:
function findnumberofaccourences(fruits, fruitName) {
var p = {
count: 0,
buyprice: undefined,
sellprice: undefined
};
fruits.forEach(function(fruit) {
if (fruit.name == fruitName) {
if (p.count == 0) {
p.buyprice = fruit.buyprice;
p.sellprice = fruit.sellprice;
}
p.count++;
}
});
return p;
}
var result = findnumberofaccourences(fruits, 'apple');
alert(JSON.stringify(result));
You can filter apples first into an array, then retrieve the first element of this array to get the data you need.
var apples = fruits.filter(function (fruit) {
return fruit.name === 'apple';
});
var p = {
count: apples.length,
buyprice: apples[0].buyprice,
sellprice: apples[0].sellprice
};
Just reverse the array first
var price = {
count: 0
};
fruits.reverse().forEach(function (fruit) {
if (fruit.name === "apple") {
price.count++;
price.buyprice = fruit.buyprice;
price.sellprice = fruit.sellprice;
}
})
console.log(price)
// restore original order in fruits array (if you are going to use it)
fruits.reverse();
Note that this will reverse your array in place, so you'll need to do a fruits.reverse() once again to get back the fruits array elements in the original order, if you are going to use fruits further down the flow. (Thanks aduch)
Well your code does not work as you expect, your example work only because apple is the last element of the array.
you need to update your for loop like this
for (var i = 0; i < fruits.length; i++) {
var name = fruits[i].name;
if (name == apple) {
if ( a === 0){
buyprice = fruits[i].buyprice;
sellprice = fruits[i].sellprice;
}
a++;
}
}
It will update buyprice and sellprice only the first time for the first apple
Your orignal code was updating buyprice and sellprice for each element of your array