1. 程式人生 > >Implement a simple iterator using javascript (node.js)

Implement a simple iterator using javascript (node.js)

The code is extremely simple, so just let the code tell you everything!

One point need to be pointed out I made use of node.js to write the following code:

/* implement a simple iterator without OOP */
function iterator(values) {
	var n = arguments.length;
	var i = 0;
	var vals = arguments;     // must keep a reference to the "arguments" object

	var returnObj = {
		hasNext: function() {
			return i < n;    // because closure keep the reference to the variable, i will get changed as next() get called.
		},
		next: function() {
			if (i >= n) {
				throw new Error("end of iteration!");
			}

			return vals[i++];
		}
	};

	if (isArray(values)) {
		n = values.length;
		vals = arguments[0];

		// support for remove() method
		returnObj.remove = function() {
			if (i === 0) {
				throw new Error("must call next method first!");
			}

			vals.splice(i-1, 1);
		};
	}

	return returnObj;

}

/* to test if the given object is an array */
function isArray(arr) {
	return arr.constructor.toString().indexOf("Array") > -1;
}


/* the following is the test code */
console.log("variable-arity version");
var iter = iterator(1, 2, 3, 4, 5, 6, 7, 8, 9, 0);
while (iter.hasNext()) {
	console.log(iter.next());
}

console.log("array version");
iter = iterator([1, 2, 3, 4, 5, 6, 7, 8, 9, 0]);
while (iter.hasNext()) {
	console.log(iter.next());
}

console.log("array version, test remove method");
var arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 0];
console.log("before remove", arr);
iter = iterator(arr);
// iter.remove();  // "must call next method first" error
while (iter.hasNext()) {
	var item = iter.next();
	if (item % 2 === 0) {
		iter.remove();
	}
}

console.log("after remove", arr);

// console.log(iter.next());   // "end of iteration" error

As you can see, it is not that trival. I am gonna show you another problem as a bonus (c/c++ version):

Requirement: extract all the numbers at the odd position from a sequence of numbers, and then sort them in an ascending order. After that, sort the left numbers in a descending order, and finally merge these two sorted sequences.

e.g., 1 2 7 4 8 6

odd: 1 7 8

even: 2 4 6

after sort

odd: 1 7 8

even: 6 4 2

after merge

1 6 7 4 8 2

#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
using namespace std;

bool greater(int a, int b)
{
    return a > b;
}

bool less(int a, int b)
{
    return a < b;
}

vector<int> splitStr(string str,string pattern)
{
    int pos;
    vector<int> result;
    str += pattern;
    int size=str.size();

    for(int i=0; i<size; i++)
    {
        pos=str.find(pattern,i);
        if(pos<size)
        {
            string s=str.substr(i,pos-i);
            result.push_back(atoi(s.c_str()));
            i=pos+pattern.size()-1;
        }
    }
    return result;
}

vector<int> sortVec(vector<int> numVec)
{
    vector<int> oddVec;
    vector<int> evenVec;
    vector<int> result;
    for(unsigned int i = 0; i < numVec.size(); i++)
    {
        if(!(i & 0x1))
        {
            oddVec.push_back(numVec[i]);
        }
        else
        {
            evenVec.push_back(numVec[i]);
        }
    }

    sort(oddVec.begin(), oddVec.end(), less);
    sort(evenVec.begin(), evenVec.end(), greater);

    unsigned int pos = 0;
    unsigned int j = 0;
    while(j < numVec.size())
    {
        result.push_back(oddVec[pos]);
        ++ j;
        if(j == numVec.size())
            break;
        result.push_back(evenVec[pos]);
        ++ j;
        ++ pos;
    }
    return result;
}

int main()
{
    string str;
    vector<int> numVec;
    vector<int> result;
    getline(cin, str);
    numVec = splitStr(str, " ");
    result = sortVec(numVec);
    for(unsigned int i = 0; i < result.size(); i++)
        cout << result[i] << " ";
    cout << endl;

    return 0;
}