Извлеките строку между двумя & ldquo; | & rdquo; [Дубликат]

Мое предположение заключается в том, что, поскольку при разработке javascript они считали, что элементное сравнение было редко используемой функцией, поэтому оно никогда не помещалось в язык.

Эта функция довольно распространена на популярных языках; Java не поддерживает его, C # не поддерживает его, C ++ stl-типы не поддерживают его.

Элементное сравнение довольно дорогое и сложное по сравнению с эталонным сравнением.

В идеальном мире все можно сравнить по ссылке, так что все два объекта, которые имеют одно и то же состояние, будут иметь одну и ту же ссылку, что позволяет нам действительно дешево проверять равенство, просто сравнивая их внутренние виртуальные адреса с простым сопоставлением чисел.

К сожалению, мы не живем в идеальном мире, и выше это возможно только для строк с пулом строк, а также с некоторыми другими относительно дорогими вариантами кэширования относительно памяти.

Некоторые языки, такие как Prolog и Haskell, позволяют сравнивать по значению; например

myProgram :- 
    Object1 = [1, "something", true, [1,[[], []], true,[false]]],
    Object2 = [1, "something", false, [1,[[], []], true,[false]]],
    Object3 = [1, "something", true, [1,[[], []], true,[false]]],
    Object4 = [1, "something", false, [1,[[], []], true,[false]]],
    (Object1 = Object2 
        -> write("first test passed.")    
        ; write("first test failed\n")),
    (Object1 = Object3 
        -> write("second test passed!\n")
        ; write("second test failed!\n")),
    (Object2 = Object4
        -> write("third test passed!\n")
        ; write("third test failed!")).

Вы можете реализовать свой собственный глубокий компаратор на любом языке, используя карту от конструктора к компаратору для этого конструктора. Поскольку JavaScript не имеет карт из ничего, кроме строки в объект, а клиенты javascript не имеют доступа к внутреннему уникальному идентификатору объектов, нам нужно использовать таблицу с конструктором, пары компараторов, что-то вроде ниже.

class MyList {
    constructor(a, b) {
        this.head_ = a;
        this.tail_ = b;
    }
    getHead() {
        return this.head_;
    }
    getTail() {
        return this.tail_;
    }
    setHead(x) {
        this.head_ = x;
    }
    setTail(x) {
        this.tail_ = x;
    }
    equals(other) {
        if (typeof other !== 'object') {
            console.log(other, 'EEP');
            return false;
        }
        if (!(other instanceof MyList)) {
            console.log(other, 'EEP');
            return false;
        }

        var h = this.head_;
        var ho = other.getHead();
        var cmp1 = comparatorof(h);
        if (!cmp1(h, ho)) {
            return false;
        }
        var t = this.tail_;
        var to = other.getTail();
        var cmp2 = comparatorof(t);
        if (!cmp2(t, to)) {
            return false;
        }

        return true;
    }
}

var object1 = {
    0: "one",
    1: "two",
    2: ["one", "two", []],
    something: {
        1: [false, true]
    }
};

function strictComparator(a, b) {
    return a === b;
}

// given any object, tries finding a function for comparing 
// that object to objects of the same kind. Kind being
// used loosely, since some objects like null resist being categorized,
// so these objects need special alteration of the comparatorof itself.
function comparatorof(x) {
    if (x === null || x === undefined) {
        return strictComparator;
    }

    x = Object(x); // promote primitives to objects
    var ctor = x.constructor;
    var c2ct = ctorToComparatorTable;
    var n = c2ct.length;

    for (var i = 0; i < n; ++i) {
        var record = c2ct[i];
        var keyCtor = record[0];

        if (keyCtor === ctor) {
            return record[1];
        }
    }
    throw new TypeError('no comparator exists for ' + x);
}

var ctorToComparatorTable = [
    [String, function(a, b) {
        return a == b;
    }],
    [Object, function(a, b) {
        for (var key in a) {
            var avalue = a[key];
            var bvalue = b[key];
            var cmp = comparatorof(avalue);

            if (!cmp(avalue, bvalue)) {
                return false;
            }
        }

        return true;
    }],
    [Number, function(a, b) {
        return a == b;
    }],
    [Boolean, function(a, b) {
        return a == b;
    }],
    [Array, function(as, bs) {
        if (typeof bs !== 'object') {
            return false;
        }
        var nAs = as.length;
        var nBs = bs.length;

        if (nAs !== nBs) {
            return false;
        }

        for (var i = 0; i < nAs; ++i) {
            var a = as[i];
            var b = bs[i];
            var cmp = comparatorof(a);

            if (!cmp(a, b)) {
                return false;
            }
        }

        return true;
    }],
    [MyList, function(a, b) {
        return a.equals(b);
    }]
];

// true
console.log(comparatorof([])([new MyList(1, new MyList(2, 3))], [new MyList(1, new MyList(2, 3))]));
// true
console.log(comparatorof([])([{}, new MyList(1, new MyList(2, 3))], [{}, new MyList(1, new MyList(2, 3))]));
// false
console.log(comparatorof([])([{}, new MyList(1, new MyList(2, 3))], [{}, new MyList(1, new MyList(3, 3))]));
// true
console.log(comparatorof({})({
    1: 'one',
    one: '1',
    x: new MyList(1, {})
}, {
    1: 'one',
    one: '1',
    x: new MyList(1, {})
}));
// true
console.log(comparatorof(2)(
    3,
    3
));
//true
console.log(comparatorof(true)(
    true,
    true
));
//false
console.log(comparatorof([])(
    [1, 2, new MyList(1, 2)], [1, 2, new MyList(4, 9)]
));
// true
console.log(comparatorof([])(
    [1, 2, new MyList(1, 2), null], [1, 2, new MyList(1, 2), null]
));
// false
console.log(comparatorof(null)(
    null,
    undefined
));
// true
console.log(comparatorof(undefined)(
    undefined,
    undefined
));
// true
console.log(comparatorof(null)(
    null,
    null
));

Одна большая проблема заключается в том, что ES6 уже полон функций, которые несовместимы с JScript и Nashorn JJS, а также с ActionScript, что язык может также быть переименован как совершенно новый язык каждые несколько месяцев, учитывая, что это эффективно то, что вы получить, когда вы добавляете новые функции на язык, который нарушает совместимость со старыми версиями, которые не могут быть реплицированы без дополнительного уровня eval.

Эта проблема длится долго, когда на одной стороне у вас минимальный язык как Lisp, который «легче» (до сих пор не может перегружать «оператор»), чтобы внедрить функции «первого класса», не нарушая обратной совместимости, а затем у вас есть такие языки, как Perl, которые не могут быть расширены с помощью новых первоклассных ключевых слов без дополнительной оценки Эйер. JavaScript выбрал второй подход и, как правило, обходит последствия, используя вспомогательные объекты, такие как Math, Object, чтобы вводить новые функции, но в любое время, когда он хочет добавить «конструкции первого класса», он в конечном итоге нарушает обратную совместимость.

доказательство концепции, в Lisp вы можете перегрузить == operator, тогда как в JavaScript вы не можете, а в Perl вы можете, но через механизм, который резервирует ключевые слова.

6
задан RockScience 22 April 2014 в 02:31
поделиться

1 ответ

Как вы можете читать? strsplit, аргумент split в функции strsplit является регулярным выражением . Следовательно, либо вам нужно избежать вертикальной полосы (это специальный символ)

strsplit(r,split='\\|and')

, либо вы можете выбрать fixed = TRUE, чтобы указать, что split не является регулярным выражением

strsplit(r,split='|and',fixed=TRUE)
20
ответ дан RockScience 25 August 2018 в 08:42
поделиться
Другие вопросы по тегам:

Похожие вопросы: