Для тех, кто должен решить эту проблему с помощью Oracle 9i (или ранее), вам, вероятно, придется использовать SYS_CONNECT_BY_PATH, так как LISTAGG недоступен.
Чтобы ответить на OP, следующий запрос отобразит PID из таблицы A и объединить все столбцы DESC из таблицы B:
SELECT pid, SUBSTR (MAX (SYS_CONNECT_BY_PATH (description, ', ')), 3) all_descriptions
FROM (
SELECT ROW_NUMBER () OVER (PARTITION BY pid ORDER BY pid, seq) rnum, pid, description
FROM (
SELECT a.pid, seq, description
FROM table_a a, table_b b
WHERE a.pid = b.pid(+)
)
)
START WITH rnum = 1
CONNECT BY PRIOR rnum = rnum - 1 AND PRIOR pid = pid
GROUP BY pid
ORDER BY pid;
Также могут быть экземпляры, в которых ключи и значения содержатся в одной таблице. Следующий запрос может использоваться там, где нет таблицы A, и существует только таблица B:
SELECT pid, SUBSTR (MAX (SYS_CONNECT_BY_PATH (description, ', ')), 3) all_descriptions
FROM (
SELECT ROW_NUMBER () OVER (PARTITION BY pid ORDER BY pid, seq) rnum, pid, description
FROM (
SELECT pid, seq, description
FROM table_b
)
)
START WITH rnum = 1
CONNECT BY PRIOR rnum = rnum - 1 AND PRIOR pid = pid
GROUP BY pid
ORDER BY pid;
Все значения могут быть переупорядочены по желанию. Отдельные конкатенированные описания могут быть переупорядочены в предложении PARTITION BY, и список PID может быть переупорядочен в конечном предложении ORDER BY.
Альтернативно: могут быть моменты, когда вы хотите объединить все значения из целой таблицы в одну строку.
Ключевая идея здесь заключается в использовании искусственного значения для группы описаний, которые будут конкатенированы.
В следующем запросе константа string ' 1 ', но любое значение будет работать:
SELECT SUBSTR (MAX (SYS_CONNECT_BY_PATH (description, ', ')), 3) all_descriptions
FROM (
SELECT ROW_NUMBER () OVER (PARTITION BY unique_id ORDER BY pid, seq) rnum, description
FROM (
SELECT '1' unique_id, b.pid, b.seq, b.description
FROM table_b b
)
)
START WITH rnum = 1
CONNECT BY PRIOR rnum = rnum - 1;
Индивидуальные конкатенированные описания могут быть переупорядочены в предложении PARTITION BY.
Несколько других ответов на этой странице также упомянули об этом чрезвычайно полезная ссылка: https://oracle-base.com/articles/misc/string-aggregation-techniques
Вы должны сделать
const result = {
showType: function() {
Так что вы можете сделать getShape().showType()
.
Это то, что вы спрашиваете?
Насколько я понимаю из требований к домашней работе, это проверяет ваше понимание JavaScript Closures .
Вот как можно использовать замыкания для решения:
Во-первых, данный базовый код уже возвращает объект результата. Возвращаемый объект результата предоставляет методы, которые можно вызвать извне: showType()
, describe()
, increase()
, whatIs()
. То, что вы пишете внутри этих функций, имеет доступ к области действия функции getShape()
.
Я создал переменную с именем segments
и функцию с именем getName()
внутри функции getShape()
. Как видите, они могут быть доступны только внутри функции getShape()
.
Вот полный код ниже:
const getShape = function (countOfTypes = 3) {
// Create a Shape Object
let segments = countOfTypes;
function getName() {
if (segments < 3) {
return null;
} else if (segments === 3) {
return "triangle";
} else if (segments === 4) {
return "quadrilateral";
} // vice versa
}
const result = {
showType() {
// Return (Number) the current count of types
return Number (segments);
},
describe() {
// log 'The shape you created is a *** composed by * segments
if (getName() === null) {
console.log("A shape needs to have at least 3 segments, it will be set to 3, and set the type property value to 3");
} else {
console.log(`The shape you created is a ${getName()} composed by ${segments} segments`);
}
},
increase() {
// Increase the type property of a created shape by 1 and log the appropriate sentence in describe()
segments++;
result.describe();
},
whatIs() {
// Open a new window that links to https://en.wikipedia.org/wiki/Polygon
window.open("https://en.wikipedia.org/wiki/Polygon");
}
};
return result;
};
//Test and use Cases
const square = getShape(3);
square.describe();
square.increase();
Композиция объектов - это создание объектов из объектных и примитивных типов данных (логические значения, строки, числа и т. Д.). Вы хотите избегать использования классов, но хотите использовать общие методы для объектов тогда вы правы - заводская функция была бы жизнеспособным решением. Этот термин называется конкатенативным наследованием - составление объектов путем расширения существующего объекта новыми свойствами :
blockquote>Object.assign(properties, method(properties), ...)
Я не могу написать в рамках вашей домашней работы Надеюсь, это поможет вам в правильном направлении. Следующая демка получит от 3 до 20 от пользователя, создаст объект и из свойств этого объекта сгенерирует HTML с именем многоугольника, а также ссылку и изображение указанного многоугольника. Я оставляю вам описание.
Plunker
Демо
Подробности прокомментированы в демо
<!DOCTYPE html> <html> <head> <style> form { font: 400 16px/1.25 Consolas } input, output, button { display: inline-block; font: inherit } input { text-align: center; } img { display: block; margin: 0 auto; height: 250px; width: auto; } </style> </head> <body> <form id='poly' onsubmit='return false'> <fieldset> <legend>Regular Polygons</legend> <label> Sides: </label> <input id='qty' type='number' min='3' max='20'> <button id='btn'>GO</button> </fieldset> <fieldset id='view'></fieldset> </form> <script> /* Composite Objects */ /* getType has the name() method which will convert props.sides into the proper index of the types array to get the correct value for prop.type */ const getType = (props, types) => ({ name: () => { props.type = types[props.sides - 3]; } }); /* getLinx has the link() and image() methods props.type is used by the former and props.sides and the dir array are used by the later to interpolate strings into template literals that become urls for props.url and props.img. */ const getLinx = (props, dir) => ({ link: () => { props.url = `https://en.wikipedia.org/wiki/${props.type}`; }, image: () => { switch (props.sides) { case 4: props.img = `https://upload.wikimedia.org/wikipedia/commons/3/3d/Six_Quadrilaterals.svg`; break; default: props.img = `https://upload.wikimedia.org/wikipedia/commons/${dir[props.sides - 3]}/Regular_polygon_${props.sides}_annotated.svg`; break; } } }); /* polygon() function factory passes 2 parameters sides (Number) and tag (String) props is the object that will have the three methods name(), link(), and image() by concatenative inheritance using Object.assign(). */ const polygon = (sides, tag) => { const types = ["Triangle", "Quadrilateral", "Pentagon", "Hexagon", "Septagon", "Octogon", "Nonagon", "Decagon", "Undecagon", "Dodecagon", "Tridecagon", "Tetradecagon", "Pentadecagon", "Hexadecagon", "Heptadecagon", "Octadecagon", "Enneadecagon", "Icosagon"]; const dir = ["e/eb", "3/3d", "0/01", "3/38", "7/75", "e/e5", "b/ba", "b/b9", "f/f8", "0/06", "a/a6", "e/e1", "d/d0", "e/e4", "c/c6", "d/d8", "1/18", "2/23"]; let props = { tag: tag, sides: sides, type: '', url: '', img: '', desc: '' }; return Object.assign(props, getType(props, types), getLinx(props, dir)); }; /* DOM Interface */ /* HTMLFormControlsCollection is a terse API that references tags by id or name */ const poly = document.forms.poly; const qty = poly.qty; const view = poly.view; /* #btn is regustered to the click event. When triggered, the value of #qty (.valueAsNumber) and the number of #view's chid elements (.childElementCount) become arguments for the function displayPoly(). */ poly.btn.addEventListener('click', (e) => { const vert = qty.valueAsNumber; const count = view.childElementCount; displayPoly(vert, count); }); /* displayPoly() passes the number from #qty and interpolates the number #view with a generic word to create a unique string to pass it to polygon() as the 2nd argument. Next, the object creayed by polygon is returned and referenced as shape. shape's methods are invoked and then the new values are generated. The values of type, url, and img are interpolated into a string which is then rendered as HTML and prepended to #view. */ const displayPoly = (number, index) => { let name = `shape${index}`; let shape = polygon(number, name); shape.name(); shape.link(); shape.image(); let Type = shape.type; let Url = shape.url; let Img = shape.img; let item = ` <figure id='${name}'> <figcaption title='${shape.sides} Sides'>${Type}</figcaption> <a href='${Url}'> <img src='${Img}'> </a> </figure> `; view.insertAdjacentHTML('afterbegin', item); return false; }; </script> </body> </html>