값 'Dog'
과 배열이 ['Cat', 'Dog', 'Bird']
있습니다.
배열을 반복하지 않고 배열에 존재하는지 어떻게 확인합니까? 값이 존재하는지 확인하는 간단한 방법이 있습니까?
값 'Dog'
과 배열이 ['Cat', 'Dog', 'Bird']
있습니다.
배열을 반복하지 않고 배열에 존재하는지 어떻게 확인합니까? 값이 존재하는지 확인하는 간단한 방법이 있습니까?
답변:
당신이 찾고있는 것 include?
:
>> ['Cat', 'Dog', 'Bird'].include? 'Dog'
=> true
%w(Cat Dog Bird).include? 'Dog'
#include?
여전히 루핑을 수행 한다는 점에 유의하십시오 . 그러나 코더는 루프를 명시 적으로 작성하여 저장됩니다. 루프를 반복하지 않고 작업을 수행하는 답변을 추가했습니다.
이 in?
방법 에 ActiveSupport
@campaterson가 가리키는 아웃과 같은 버전 3.1 이후 (레일의 일부). 따라서 Rails 내에서 또는 다음 require 'active_support'
과 같이 쓸 수 있습니다.
'Unicorn'.in?(['Cat', 'Dog', 'Bird']) # => false
OTOH, Ruby 자체 에는 in
연산자 나 #in?
메소드 가 없습니다. 비록 이전에, 특히 Yusuke Endoh에 의해 제안되었지만 루비 코어의 최고 수준의 멤버 인 .
다른 사람에 의해 지적, 반대 방법이 include?
존재하며, 모든 Enumerable
포함의 Array
, Hash
, Set
, Range
:
['Cat', 'Dog', 'Bird'].include?('Unicorn') # => false
배열에 많은 값이 있으면 O(n)
해시에 대한 조회가 일정한 시간 (예 :)으로 바뀌면서 값이 하나씩 차례로 확인 됩니다 (예 :) O(1)
. 예를 들어 배열이 일정하면 대신 Set 을 사용하는 것이 좋습니다 . 예 :
require 'set'
ALLOWED_METHODS = Set[:to_s, :to_i, :upcase, :downcase
# etc
]
def foo(what)
raise "Not allowed" unless ALLOWED_METHODS.include?(what.to_sym)
bar.send(what)
end
빠른 테스트는 호출하는 것을 알 수 include?
10 요소를하는 Set
동등에 전화보다 빠른 3.5 배에 관한 것입니다Array
(요소가 발견되지 않는 경우).
마지막 닫는주의 사항 : 사용시주의해야 include?
켜짐 Range
, 그래서 참조, 미묘한가 다큐먼트 와 비교 cover?
...
#in?
코어에 포함 되어 있지 않지만 Rails를 사용하는 경우 사용할 수 있습니다. api.rubyonrails.org/classes/Object.html#method-i-in-3F (나는 이것이 Rails의 질문이 아니라 Ruby라는 것을 알고 있지만 #in?
Rails 에서 사용하려는 사람에게 도움이 될 수 있습니다 . Rails에 추가 된 것 같습니다. 3.1 apidock.com/rails/Object/in%3F
시험
['Cat', 'Dog', 'Bird'].include?('Dog')
사용 Enumerable#include
:
a = %w/Cat Dog Bird/
a.include? 'Dog'
또는 여러 테스트가 수행되면 1 루프를 제거 include?
하고 다음을 사용하여 O (n) 에서 O (1) 로 이동할 수 있습니다 .
h = Hash[[a, a].transpose]
h['Dog']
블록별로 확인하려면 any?
또는을 시도하십시오 all?
.
%w{ant bear cat}.any? {|word| word.length >= 3} #=> true
%w{ant bear cat}.any? {|word| word.length >= 4} #=> true
[ nil, true, 99 ].any? #=> true
열거 가능 참조 을 참조하십시오.
내 영감 "에서 온 배열 루비에서 모든 항목이있는 경우 평가 "
루비에는 배열에서 요소를 찾는 11 가지 방법이 있습니다.
바람직한 하나는 include?
반복 된 액세스에 대해 호출 후 creat에 세트하고, 또는 include?
나 member?
.
다음은 모두입니다.
array.include?(element) # preferred method
array.member?(element)
array.to_set.include?(element)
array.to_set.member?(element)
array.index(element) > 0
array.find_index(element) > 0
array.index { |each| each == element } > 0
array.find_index { |each| each == element } > 0
array.any? { |each| each == element }
array.find { |each| each == element } != nil
array.detect { |each| each == element } != nil
true
요소가 존재하면 모두 ish 값을 반환합니다 .
include?
선호되는 방법입니다. for
내부적 으로 C 언어 루프를 사용 하여 요소가 내부 rb_equal_opt/rb_equal
함수 와 일치 할 때 중단됩니다 . 반복 멤버쉽 확인을위한 세트를 작성하지 않으면 훨씬 효율적으로 얻을 수 없습니다.
VALUE
rb_ary_includes(VALUE ary, VALUE item)
{
long i;
VALUE e;
for (i=0; i<RARRAY_LEN(ary); i++) {
e = RARRAY_AREF(ary, i);
switch (rb_equal_opt(e, item)) {
case Qundef:
if (rb_equal(e, item)) return Qtrue;
break;
case Qtrue:
return Qtrue;
}
}
return Qfalse;
}
member?
Array
클래스 에서 재정의되지 않고 Enumerable
모든 요소를 문자 그대로 열거 하는 모듈 에서 최적화되지 않은 구현을 사용합니다 .
static VALUE
member_i(RB_BLOCK_CALL_FUNC_ARGLIST(iter, args))
{
struct MEMO *memo = MEMO_CAST(args);
if (rb_equal(rb_enum_values_pack(argc, argv), memo->v1)) {
MEMO_V2_SET(memo, Qtrue);
rb_iter_break();
}
return Qnil;
}
static VALUE
enum_member(VALUE obj, VALUE val)
{
struct MEMO *memo = MEMO_NEW(val, Qfalse, 0);
rb_block_call(obj, id_each, 0, 0, member_i, (VALUE)memo);
return memo->v2;
}
Ruby 코드로 변환하면 다음과 같은 작업이 수행됩니다.
def member?(value)
memo = [value, false, 0]
each_with_object(memo) do |each, memo|
if each == memo[0]
memo[1] = true
break
end
memo[1]
end
모두 include?
와 member?
때문에 O (n)은 시간 복잡도가 모두 기대 값의 첫번째 발생의 배열을 검색.
Set을 사용하여 배열의 해시 표현을 먼저 생성해야하는 비용으로 O (1) 액세스 시간을 얻을 수 있습니다. 동일한 어레이에서 멤버십을 반복해서 확인하면이 초기 투자가 빠르게 보상받을 수 있습니다. Set
C에서는 구현되지 않지만 일반 Ruby 클래스로 구현되지만 여전히 기본의 O (1) 액세스 시간 @hash
이 가치가 있습니다.
Set 클래스의 구현은 다음과 같습니다.
module Enumerable
def to_set(klass = Set, *args, &block)
klass.new(self, *args, &block)
end
end
class Set
def initialize(enum = nil, &block) # :yields: o
@hash ||= Hash.new
enum.nil? and return
if block
do_with_enum(enum) { |o| add(block[o]) }
else
merge(enum)
end
end
def merge(enum)
if enum.instance_of?(self.class)
@hash.update(enum.instance_variable_get(:@hash))
else
do_with_enum(enum) { |o| add(o) }
end
self
end
def add(o)
@hash[o] = true
self
end
def include?(o)
@hash.include?(o)
end
alias member? include?
...
end
보시다시피 Set 클래스는 내부 @hash
인스턴스를 만들고 모든 객체를 매핑 true
한 다음 다음을 사용하여 멤버십을 확인합니다.Hash#include?
해시 클래스에서 O (1) 액세스 시간으로 구현 된 .
다른 7 가지 방법은 모두 덜 효율적이므로 다루지 않습니다.
실제로 위에 나열된 11 이상의 O (n) 복잡도를 가진 훨씬 더 많은 메소드가 있지만 첫 번째 일치를 깨지 않고 전체 배열을 스캔하기 때문에 나열하지 않기로 결정했습니다.
이것을 사용하지 마십시오 :
# bad examples
array.grep(element).any?
array.select { |each| each == element }.size > 0
...
11
열거 한 방법에 대해 질문하겠습니다 . 첫째, 당신은 거의 셀 수 index
와 find_index
(나 find
하고 detect
는 동일한 방법 단지 다른 이름이기 때문에, 별도의 방법으로). 두 번째로 끝나는 모든 표현 > 0
이 잘못되었습니다. 확실히 감독이었습니다. (계속)
arr.index(e)
예를 들어 ... 은 0
if를 반환 합니다 arr[0] == e
. 없는 경우 arr.index(e)
반품 을 회수 합니다 . 하나가 검색되는 경우, 그러나, 사용할 수 없습니다 에서 . (와 동일한 문제이며 , 목록에 없습니다.). 배열을 세트로 변환 한 다음 세트 메소드를 사용하는 것은 약간의 확장입니다. 그렇다면 배열의 키와 임의 값을 사용하여 해시로 변환 한 다음 해시 방법을 사용하십시오. 집합으로 변환해도 괜찮은 경우와 같이 사용할 수있는 다른 집합 방법이 있습니다 . (계속)nil
e
index
nil
arr
rindex
!arr.to_set.add?(e)
arr.count(e) > 0
, arr != arr.dup.delete(e)
, arr != arr - [e]
와 arr & [e] == [e]
. select
그리고 또한 고용 할 수 있습니다 reject
.
몇 가지 답변이 제안 Array#include?
하지만 중요한 한 가지주의 사항이 있습니다. 소스를보고 Array#include?
루핑을 수행합니다.
rb_ary_includes(VALUE ary, VALUE item)
{
long i;
for (i=0; i<RARRAY_LEN(ary); i++) {
if (rb_equal(RARRAY_AREF(ary, i), item)) {
return Qtrue;
}
}
return Qfalse;
}
루핑없이 단어 존재를 테스트하는 방법은 배열에 대한 trie 를 구성하는 것 입니다. 거기에는 많은 트리 구현 (Google "ruby trie")이 있습니다. rambling-trie
이 예에서 사용하겠습니다 .
a = %w/cat dog bird/
require 'rambling-trie' # if necessary, gem install rambling-trie
trie = Rambling::Trie.create { |trie| a.each do |e| trie << e end }
이제 우리는 sublinear를 사용하여 O(log n)
구문상의 단순성으로 다음과 같은 시간에 반복하지 않고 배열에 다양한 단어의 존재를 테스트 할 준비가되었습니다 .Array#include?
Trie#include?
trie.include? 'bird' #=> true
trie.include? 'duck' #=> false
a.each do ... end
음 ... 루프가 아닌지 확실하지 않습니다
Set#include?
효율성에 관심이있는 사람들에게 이미 언급 된 답변보다 주목하십시오 . 문자열 대신 기호를 사용하여 결합하면 O (1) 평균 사례가 될 수 있습니다 (문자열을 사용하는 경우 해시 계산은 O (n)이며 여기서 n은 문자열의 길이입니다). 또는 타사 라이브러리를 사용하려면 O (1) 최악의 경우 인 완벽한 해시를 사용할 수 있습니다.
Set
는 해시를 사용하여 멤버를 인덱싱하므로 실제로 Set#include?
는 잘 분산 된 Set
(더 구체적으로 해싱의 경우 O (input-size) 및 O (log (n / bucket-number))의 경우 O (1)이 복잡 해야 합니다. 검색)
반복하고 싶지 않다면 Arrays로 할 수있는 방법이 없습니다. 대신 Set을 사용해야합니다.
require 'set'
s = Set.new
100.times{|i| s << "foo#{i}"}
s.include?("foo99")
=> true
[1,2,3,4,5,6,7,8].to_set.include?(4)
=> true
세트는 내부적으로 해시처럼 작동하므로, 루비는 이름에서 알 수 있듯이 키의 해시를 생성하고 각 해시가 메모리의 특정 지점을 가리 키도록 메모리 맵을 생성하므로 항목을 찾기 위해 컬렉션을 반복 할 필요가 없습니다. 이전 예제는 해시로 완료되었습니다.
fake_array = {}
100.times{|i| fake_array["foo#{i}"] = 1}
fake_array.has_key?("foo99")
=> true
단점은 세트 및 해시 키에는 고유 한 항목 만 포함 할 수 있으며 많은 항목을 추가하는 경우 Ruby는 특정 키 수를 초과 한 후 전체 키를 다시 해싱하여 더 큰 키 공간에 적합한 새 맵을 작성해야한다는 것입니다. 이에 대한 자세한 내용은 " LongWest RubyConf 2014 – 집에서 만든 해시의 Big O "를 참조하십시오.
벤치 마크는 다음과 같습니다.
require 'benchmark'
require 'set'
array = []
set = Set.new
10_000.times do |i|
array << "foo#{i}"
set << "foo#{i}"
end
Benchmark.bm do |x|
x.report("array") { 10_000.times { array.include?("foo9999") } }
x.report("set ") { 10_000.times { set.include?("foo9999") } }
end
그리고 결과 :
user system total real
array 7.020000 0.000000 7.020000 ( 7.031525)
set 0.010000 0.000000 0.010000 ( 0.004816)
include?
첫 번째 히트에서 멈추지 않습니까?
include?
첫 번째 적중시 중지하지만 해당 적중이 목록의 끝에있는 경우 .... 스토리지를 위해 어레이를 사용하는 솔루션은 목록이 커짐에 따라 성능이 저하됩니다. 특히 명부. 해시 및 세트에는 그러한 문제가 없으며 정렬 된 목록과 이진 검색이 없습니다.
이 작업을 수행하는 또 다른 방법입니다. Array#index
.
배열에서 요소가 처음 나타나는 색인을 반환합니다.
예를 들면 다음과 같습니다.
a = ['cat','dog','horse']
if a.index('dog')
puts "dog exists in the array"
end
index()
또한 블록을 취할 수 있습니다 :
예를 들면 다음과 같습니다.
a = ['cat','dog','horse']
puts a.index {|x| x.match /o/}
이것은 문자 'o'를 포함하는 배열에서 첫 번째 단어의 색인을 리턴합니다.
index
여전히 배열을 반복하고 요소의 값을 반환합니다.
재미있는 사실,
식에서 *
배열 구성원을 확인 하는 데 사용할 수 있습니다 case
.
case element
when *array
...
else
...
end
조금 주목 *
when 절의 에 . 그러면 배열의 멤버쉽이 검사됩니다.
splat 연산자의 모든 일반적인 마술 동작이 적용되므로 예를 들어 array
실제로 배열이 아니라 단일 요소 인 경우 해당 요소와 일치합니다.
when
가능한 빨리 사용하여 다른 빠른 검사를 신속하게 처리 할 수 있습니다.
당신이 어떤 키 변환을위한 배수에게 시간을 확인해야하는 경우 arr
에 hash
O (1)을 확인 지금하고,
arr = ['Cat', 'Dog', 'Bird']
hash = arr.map {|x| [x,true]}.to_h
=> {"Cat"=>true, "Dog"=>true, "Bird"=>true}
hash["Dog"]
=> true
hash["Insect"]
=> false
해시 #has_key의 성능은 ? 대 배열 #include?
매개 변수 해시 #has_key? 배열 #include 시간 복잡성 O (1) 연산 O (n) 연산 액세스 유형 각 요소를 반복하는 경우 해시 [키]에 액세스 배열의 값을 반환 할 때까지 배열의 값을 찾으면 true가 반환됩니다. 해시 #has_key? 요구 요구
일회성 점검의 경우에는 사용 include?
이 좋습니다
가치있는 것에 대해, 루비 문서 는 이런 종류의 질문에 대한 놀라운 자료입니다.
또한 검색하는 배열의 길이를 기록합니다. 이 include?
방법은 배열의 크기에 따라 O (n) 복잡도를 가진 선형 검색을 실행하여 상당히 추악해질 수 있습니다.
큰 (정렬 된) 배열로 작업하는 경우 너무 어렵지 않아야하며 최악의 O (log n)를 갖는 이진 검색 알고리즘 을 작성하는 것이 좋습니다.
또는 Ruby 2.0을 사용하는 경우을 이용할 수 있습니다 bsearch
.
<=>
하지만 항상 그런 것은 아닙니다. 예를 들어 배열의 요소가 해시라고 가정합니다.
당신은 시도 할 수 있습니다:
예 : Cat 및 Dog가 배열에 존재하는 경우 :
(['Cat','Dog','Bird'] & ['Cat','Dog'] ).size == 2 #or replace 2 with ['Cat','Dog].size
대신에:
['Cat','Dog','Bird'].member?('Cat') and ['Cat','Dog','Bird'].include?('Dog')
참고 : member?
및 include?
동일합니다.
이것은 한 줄로 작업을 수행 할 수 있습니다!
우리가 사용하지 않으려는 경우 include?
에도 작동합니다.
['cat','dog','horse'].select{ |x| x == 'dog' }.any?
['Cat', 'Dog', 'Bird'].detect { |x| x == 'Dog'}
=> "Dog"
!['Cat', 'Dog', 'Bird'].detect { |x| x == 'Dog'}.nil?
=> true
['Cat', nil, 'Dog'].detect { |x| x == nil } #=> nil
. 있었 nil
발견?
이 문제에 대한 다른 방법이 있습니다.
배열이 [ :edit, :update, :create, :show ]
아마도 일곱 가지 치명적 / 휴식적인 죄 라고 가정 해 봅시다 .
그리고 아이디어와 더 장난감을 당겨 일부 문자열에서 유효한 조치를 :
"my brother would like me to update his profile"
그때:
[ :edit, :update, :create, :show ].select{|v| v if "my brother would like me to update his profile".downcase =~ /[,|.| |]#{v.to_s}[,|.| |]/}
/[,|.| |]#{v.to_s}[,|.| |]/
은``쉼표, 마침표, 공백 또는 아무것도없는 것 중 하나에 둘러싸인 동작의 이름 ''을 찾고 싶었지만 미묘한 버그가 있다고 생각합니다. "|update|"
반환 [:update]
하고 "update"
반환 []
합니다. 문자 클래스 ( [...]
)는 파이프 ( |
)를 사용 하여 문자를 구분 하지 않습니다 . 그룹 ( (...)
)으로 변경하더라도 빈 문자와 일치 할 수 없습니다. 아마 당신이 원했던 정규식은/(,|\.| |^)#{v.to_s}(,|\.| |$)/
/[,. ]/
true 또는 false뿐만 아니라 값을 반환하려면 다음을 사용하십시오.
array.find{|x| x == 'Dog'}
목록에 'Dog'이 있으면 그렇지 않으면 nil을 반환합니다.
array.any?{|x| x == 'Dog'}
당신이 경우 않는 참 / 거짓의 (값이 아닌)을 원하지만이 같은 블록에 대해 비교하려는.
이를 수행하는 또 다른 방법은 다음과 같습니다.
arr = ['Cat', 'Dog', 'Bird']
e = 'Dog'
present = arr.size != (arr - [e]).size
arr != arr - [e]
. arr & [e] == [e]
같은 줄을 따라 또 다른 방법입니다.
다양한 벤치마킹 방법의 상대 속도를보기 위해 몇 가지 벤치 마크를 실행하는 것이 항상 흥미 롭습니다.
시작, 중간 또는 끝에서 배열 요소를 찾으면 선형 검색에는 영향을 주지만 집합에 대한 검색에는 거의 영향을 미치지 않습니다.
어레이를 세트로 변환하면 처리 시간이 단축 될 수 있으므로 어레이에서 세트를 한 번 작성하거나 처음부터 세트로 시작하십시오.
벤치 마크 코드는 다음과 같습니다.
# frozen_string_literal: true
require 'fruity'
require 'set'
ARRAY = (1..20_000).to_a
SET = ARRAY.to_set
DIVIDER = '-' * 20
def array_include?(elem)
ARRAY.include?(elem)
end
def array_member?(elem)
ARRAY.member?(elem)
end
def array_index(elem)
ARRAY.index(elem) >= 0
end
def array_find_index(elem)
ARRAY.find_index(elem) >= 0
end
def array_index_each(elem)
ARRAY.index { |each| each == elem } >= 0
end
def array_find_index_each(elem)
ARRAY.find_index { |each| each == elem } >= 0
end
def array_any_each(elem)
ARRAY.any? { |each| each == elem }
end
def array_find_each(elem)
ARRAY.find { |each| each == elem } != nil
end
def array_detect_each(elem)
ARRAY.detect { |each| each == elem } != nil
end
def set_include?(elem)
SET.include?(elem)
end
def set_member?(elem)
SET.member?(elem)
end
puts format('Ruby v.%s', RUBY_VERSION)
{
'First' => ARRAY.first,
'Middle' => (ARRAY.size / 2).to_i,
'Last' => ARRAY.last
}.each do |k, element|
puts DIVIDER, k, DIVIDER
compare do
_array_include? { array_include?(element) }
_array_member? { array_member?(element) }
_array_index { array_index(element) }
_array_find_index { array_find_index(element) }
_array_index_each { array_index_each(element) }
_array_find_index_each { array_find_index_each(element) }
_array_any_each { array_any_each(element) }
_array_find_each { array_find_each(element) }
_array_detect_each { array_detect_each(element) }
end
end
puts '', DIVIDER, 'Sets vs. Array.include?', DIVIDER
{
'First' => ARRAY.first,
'Middle' => (ARRAY.size / 2).to_i,
'Last' => ARRAY.last
}.each do |k, element|
puts DIVIDER, k, DIVIDER
compare do
_array_include? { array_include?(element) }
_set_include? { set_include?(element) }
_set_member? { set_member?(element) }
end
end
내 Mac OS 랩톱에서 실행할 때 다음과 같은 결과가 발생합니다.
Ruby v.2.7.0
--------------------
First
--------------------
Running each test 65536 times. Test will take about 5 seconds.
_array_include? is similar to _array_index
_array_index is similar to _array_find_index
_array_find_index is faster than _array_any_each by 2x ± 1.0
_array_any_each is similar to _array_index_each
_array_index_each is similar to _array_find_index_each
_array_find_index_each is faster than _array_member? by 4x ± 1.0
_array_member? is faster than _array_detect_each by 2x ± 1.0
_array_detect_each is similar to _array_find_each
--------------------
Middle
--------------------
Running each test 32 times. Test will take about 2 seconds.
_array_include? is similar to _array_find_index
_array_find_index is similar to _array_index
_array_index is faster than _array_member? by 2x ± 0.1
_array_member? is faster than _array_index_each by 2x ± 0.1
_array_index_each is similar to _array_find_index_each
_array_find_index_each is similar to _array_any_each
_array_any_each is faster than _array_detect_each by 30.000000000000004% ± 10.0%
_array_detect_each is similar to _array_find_each
--------------------
Last
--------------------
Running each test 16 times. Test will take about 2 seconds.
_array_include? is faster than _array_find_index by 10.000000000000009% ± 10.0%
_array_find_index is similar to _array_index
_array_index is faster than _array_member? by 3x ± 0.1
_array_member? is faster than _array_find_index_each by 2x ± 0.1
_array_find_index_each is similar to _array_index_each
_array_index_each is similar to _array_any_each
_array_any_each is faster than _array_detect_each by 30.000000000000004% ± 10.0%
_array_detect_each is similar to _array_find_each
--------------------
Sets vs. Array.include?
--------------------
--------------------
First
--------------------
Running each test 65536 times. Test will take about 1 second.
_array_include? is similar to _set_include?
_set_include? is similar to _set_member?
--------------------
Middle
--------------------
Running each test 65536 times. Test will take about 2 minutes.
_set_member? is similar to _set_include?
_set_include? is faster than _array_include? by 1400x ± 1000.0
--------------------
Last
--------------------
Running each test 65536 times. Test will take about 4 minutes.
_set_member? is similar to _set_include?
_set_include? is faster than _array_include? by 3000x ± 1000.0
기본적으로 결과는 첫 번째 요소가 내가 원하는 요소라는 것을 보장 할 수 없다면 포함을 검색하려고하면 모든 것에 Set을 사용하도록 지시합니다. 해시에 요소를 삽입 할 때 약간의 오버 헤드가 있지만 검색 시간이 훨씬 빠릅니다. 나는 그것이 고려되어야한다고 생각하지 않습니다. 다시 검색해야 할 경우 Array를 사용하지 말고 Set을 사용하십시오. (또는 해시)
Array가 작을수록 Array 메서드가 더 빨리 실행되지만 작은 배열에서는 차이가 작을 수 있지만 여전히 유지되지는 않습니다.
"첫째", "중간"과 "마지막"의 사용을 반영 first
, size / 2
그리고 last
대한 ARRAY
의 요소 존재는 검색. 해당 요소는 ARRAY
및 SET
변수를 검색 할 때 사용됩니다 .
> 0
테스트는 형식 테스트에 >= 0
대한 것이므로 비교하는 방법에 대해 약간 변경되었습니다 index
.
Fruity와 그 방법론에 대한 자세한 내용은 README를 참조하십시오 .