PluralFormCyr( Number ; PluralForms_1250 )

Законченные решения. Заполняется по результатам дискуссий в «Практике».
Ответить
Alexei Sytch
Сообщения: 41
Зарегистрирован: 21 сен 2017, 18:48
Откуда: Минск

PluralFormCyr( Number ; PluralForms_1250 )

Сообщение Alexei Sytch » 22 янв 2018, 20:31

НАЗНАЧЕНИЕ
Согласование 3-х форм существительного с числительным: - Один, Два, Много + необязательная 4-я форма для "нет данных"
( русский, белорусский, украинский, сербский, боснийский, хорватский)
формы для выбора задаются текстом с разделителями

ФОРМАТ
Number - Число для которого надо сделать выбор
PluralForms_1250 - Список форм с разделителями, разделителями могут быть знаки абзаца ( ¶ ), звездочки( "*" ) , запятые ( , ), косые черты (/) , вертикальные черты ( | )

ПРИМЕРЫ ИСПОЛЬЗОВАНИЯ:
PluralFormCyr( 12 ; "олень|оленя|оленей|олени не найдены") = "12 оленей"
PluralFormCyr( 0 ; "олень|оленя|оленей|олени не найдены") = "олени не найдены"

ИДЕИ ДЛЯ ПРИМЕНЕНИЯ:
Удобно использовать для подписи элементов интерфейса и вывода сообщений о результатах поиска
Строчку с формами можно хранить в справочнике единиц измерений



Код: Выделить всё

// PluralFormCyr( Number ; PluralForms_1250 )
//
// Автор: Алексей Сыч
// Последнее обновление: 22 января 2017
// Версия:1
//
// Выбор из 3-х форм: - Один, Два, Много ---  Нет, Пара , Много 
//            + необязательно 4-я форма для "нет данных"
// 	формы единственного/множественного числа 
// 	для существительных с числительным 
// 	( русский, белорусский, украинский, сербский, боснийский, хорватский)
//	ФОРМАТ
// 	Number  		- Число для которого надо сделать выбор
//	PluralForms_1250 	- Список форм множественного числа с раделителями
//                          			как разделители допускаются: знаки абзаца ( ¶ ), звездочки( "*" ) , 
//				запятые ( , ), косые черты (/) , вертикальные черты ( | )
//	ПРИМЕРЫ ИСПОЛЬЗОВАНИЯ:	
// 	 PluralFormCyr(  12 ; "олень|оленя|оленей|олени не найдены") =  "12 оленей" 		
// 	 PluralFormCyr(    0 ; "олень|оленя|оленей|олени не найдены") = "олени не найдены"
//		
	
Let(	[
                 n		=GetAsNumber( Number)
	; w 		=GetAsText( Substitute( PluralForms_1250 ; [ "*" ; "¶" ] ; [ "|"; "¶" ] ; [ ","; "¶" ] ; [ "/" ; "¶" ] ) ) 
	; valueCount	=ValueCount ( w )
	; formIndex	=If(                   
				/* Форма 1 - число заканчивается на 1, исключая 11*/ 
				Mod( n; 10 )    = 1 
				 and Mod( n; 100 )  <>  11  
				 ; 1
				 ; If(    	
					/* Форма 2 - заканчивается на 2-4, исключая 12-14*/
                                                           	Mod( n; 10 ) ≥    2 
					and Mod( n; 10 ) <= 4  
					and (           Mod( n; 100 ) < 10 
						or Mod( n; 100 ) >= 20 
					        )
                                                     	 	; 2
                                                                   	/* Форма 4 если указана форма 4 для "нет данных" вместо 0 - используем ее */
                                                      		; If( 	n=0 
						and  valueCount = 4  
                                                           		; 4  
					/* Форма 3 - все остальные случаи */
                                                          			; 3 
						)  
                                              		)  
			 	) 
       	]
                              /* выбираем вариант вывода для Формы 4 или для числа */
	; 	If( 	formIndex= 4     
  			; GetValue( w ; formIndex)
			; n & " " & GetValue( w ; formIndex)        
              			)
    	)

/* 
В основе лежит аглоритм для русского языка из проекта Mozilla
http://mxr.mozilla.org/mozilla/source/intl/locale/src/PluralForm.jsm#59
function(n) n%10==1 && n%100!=11?  0 : n%10>=2 && n%10<=4 && (n%100<10||n%100>=20)  ?  1  :   2

*/

Ответить