2017-09-25 4 views
0

특정 activityname을 반환하는 알고리즘을 작성합니다. 우리의 기능에서전역 변수를 사용하지 않는 재귀 알고리즘의 반환 값

우리는 activity의 가치를 제공하고, 우리의 배열에 존재하는 경우 name의 값이 반환됩니다

예 :

findMatch('scuba diving', activityItems) = 'Beach' 

const activityItems = [ 
    { 
     name: 'Sunday', 
     items: [ 
      { 
       name: 'Gym', 
       activity: 'weights', 
      }, 
     ], 
    }, 
    { 
     name: 'Monday', 
     items: [ 
      { 
       name: 'Track', 
       activity: 'race', 
      }, 
      { 
       name: 'Work', 
       activity: 'meeting', 
      }, 
      { 
       name: 'Swim', 
       items: [ 
        { 
         name: 'Beach', 
         activity: 'scuba diving', 
        }, 
        { 
         name: 'Pool', 
         activity: 'back stroke', 
        }, 
       ], 
      }, 
     ],  
    }, 
    {} ... 
    {} ... 
]; 

내 구현 :

let match = ''; 
const findMatch = (activity, activityItems) => { 
    for (let i = 0; i < activityItems.length; i += 1) { 
     if (activityItems[i].activity === activity) { 
      match = activityItems[i].name; 
      return match; 
     } 

     if (activityItems[i].items && findMatch(activity, activityItems[i].items)) { 
      return match; 
     } 
    } 

    return false; 
}; 

그러나 전역 변수를 사용하기 때문에 구현이 마음에 들지 않습니다. 그것없이 올바른 값을 반환 할 수있는 방법이 있습니까?

내가 좋아하는 일을 시도 :

const findMatch = (activity, activityItems) => { 
    for (let i = 0; i < activityItems.length; i += 1) { 
     if (activityItems[i].activity === activity) { 
      return activityItems[i].name;    
     } 

     if (activityItems[i].items) { 
      return findMatch(activity, activityItems[i].items); 
     } 
    } 

    return false; 
}; 

그러나 이것은 항상 false 또는 undefined를 반환합니다.

제안 사항?

답변

1

왜 전역 변수를 유지해야합니까? 이름이 있으면 그냥 반환하거나 그렇지 않으면 null을 반환하십시오. 지역 변수 재귀 검색의 결과를 유지에만 반환이 null없는 경우 :

const findMatch = (activity, activityItems) => { 
    for (let i = 0; i < activityItems.length; i++) { 
     if (activityItems[i].activity === activity) 
      return activityItems[i].name; 

     if (activityItems[i].items) { 
      let match = findMatch(activity, activityItems[i].items); 
      if (match) return match; 
     } 
    } 

    return null; 
}; 
1

Array.prototype.find 방법에 내장 값이 발견되지 않는 경우 undefined를 반환, 그래서 나는 그 모범을 따를 것 일치하지 않는 결과로 undefined을 사용합니다.

나는 또한 for of을 사용하여 기능을 구현하려고합니다.

const activityItems = [ 
 
    {name: 'Sunday',items: [{name: 'Gym',activity: 'weights'}]}, 
 
    {name: 'Monday',items: [{name: 'Track',activity: 'race'}, 
 
     {name: 'Work',activity: 'meeting'}, 
 
     {name: 'Swim',items: [{name: 'Beach',activity: 'scuba diving'}, 
 
      {name: 'Pool',activity: 'back stroke'}]}]}, 
 
    {}, 
 
    {} 
 
]; 
 

 
const findMatch = (needle, haystack) => { 
 
    for (let {activity, name, items} of haystack) { 
 
    if (activity == needle) return name; 
 
    if (items && (items = findMatch(needle, items))) return items; 
 
    } 
 
    return undefined; 
 
} 
 

 

 
console.log(findMatch('scuba diving', activityItems))

은 또한 당신이 원하는 특정 속성을 잡기 위해 for of 루프에서 destructuring의 assingment를 사용합니다. 나는 재귀 호출의 결과를 할당하기 위해 items 변수를 재사용했다. 이 작업을 수행 할 필요는 없지만이 목적을 위해 변수를 선언하지 않고도 시간이 조금 단축됩니다.


가 여기에 린터를 만족하기 위해 .reduce()를 사용하여 버전,하지만 지금 우리가 잃어버린 단락 :-(.

const activityItems = [ 
 
    {name: 'Sunday',items: [{name: 'Gym',activity: 'weights'}]}, 
 
    {name: 'Monday',items: [{name: 'Track',activity: 'race'}, 
 
     {name: 'Work',activity: 'meeting'}, 
 
     {name: 'Swim',items: [{name: 'Beach',activity: 'scuba diving'}, 
 
      {name: 'Pool',activity: 'back stroke'}]}]}, 
 
    {}, 
 
    {} 
 
]; 
 

 
const findMatch = (needle, haystack) => { 
 
    return haystack.reduce((res, {activity, name, items}) => 
 
    res !== undefined ? res : 
 
    activity == needle ? name : 
 
    items && findMatch(needle, items) 
 
    , undefined) 
 
} 
 

 

 
console.log(findMatch('scuba diving', activityItems))


또 하나의 버전을, 기능적 기술을 사용하여, 내장 된 방법없이. 만약 기능적 코딩이 당신이 추구 한 것이라면, 나는이 접근 방식을 취할 것입니다.OK


const activityItems = [ 
 
    {name: 'Sunday',items: [{name: 'Gym',activity: 'weights'}]}, 
 
    {name: 'Monday',items: [{name: 'Track',activity: 'race'}, 
 
     {name: 'Work',activity: 'meeting'}, 
 
     {name: 'Swim',items: [{name: 'Beach',activity: 'scuba diving'}, 
 
      {name: 'Pool',activity: 'back stroke'}]}]}, 
 
    {}, 
 
    {} 
 
]; 
 

 
const findMatch = (needle, haystack) => { 
 
    if (!haystack || !haystack.length) { 
 
    return undefined; 
 
    } 
 
    const {activity, name, items} = haystack[0]; 
 
    return activity == needle ? name : 
 
     findMatch(needle, items) || findMatch(needle, haystack.slice(1)); 
 
} 
 

 
console.log(findMatch('scuba diving', activityItems))
, 하나 더. 마지막 것의 작은 변형입니다. 꼬리 재귀를 사용하는 순전히 함수형 프로그래밍에 대해 말하고 있기 때문에 꼬리에서 머리를 분리하는 매개 변수를 정의하는 것이 유용합니다. 확산 구문rest 구문은이 작업을 쉽게 만듭니다.

const activityItems = [ 
 
    {name: 'Sunday',items: [{name: 'Gym',activity: 'weights'}]}, 
 
    {name: 'Monday',items: [{name: 'Track',activity: 'race'}, 
 
     {name: 'Work',activity: 'meeting'}, 
 
     {name: 'Swim',items: [{name: 'Beach',activity: 'scuba diving'}, 
 
      {name: 'Pool',activity: 'back stroke'}]}]}, 
 
    {}, 
 
    {} 
 
]; 
 

 
const findMatch = (needle, head, ...tail) => { 
 
    if (!head) { 
 
    return undefined; 
 
    } 
 
    const {activity, name, items} = head; 
 
    return activity == needle ? name : 
 
     items && findMatch(needle, ...items) || findMatch(needle, ...tail); 
 
} 
 

 
console.log(findMatch('scuba diving', ...activityItems))

+0

eslint 오류 :'반복자는/발전기는이 가이드를 할 수 있도록 너무 헤비급 재생기-런타임을 필요로합니다. 별도로 루프는 배열 반복을 피하기 위해 금지되어야합니다. 구문은 – user2456977

+0

+ eslint : 활동 및 이름이 다시 할당되지 않기 때문에 비용을 변경하십시오. 그런 다음 항목을 재사용하는 대신 다른 변수를 추가하십시오 .. – user2456977

+0

위의 오류가 발생합니다. 따라서 변환기가 관련되어 있어야합니까? "가이드"가 그들을 허용하지 않는 이유와 그 이유는 무엇입니까? transpiler 사용의 요점은 유용하고 새로운 구문 기능을 피할 수있게 사용하는 것입니다. '제한없는 구문 (no-restricted-syntax)'구성은 절대적인 것과는 거리가 먼 의견을 표현합니다. 배열 반복 (iteration) 메서드에 대해 for of를 사용할 것입니다. 나는'.reduce()'를 사용하기 위해 이것을 다시 쓸 수 있다고 생각하지만 거기에는 이득이 없다. – llama