OrderByパイプの問題


97

このコードをAngualr 1からAngular 2に変換できません。

ng-repeat="todo in todos | orderBy: 'completed'"

これは私がティエリーテンプリエの答えに従って行ったことです:

コンポーネントテンプレート:

*ngFor="#todo of todos | sort"

コンポーネントコード:

@Component({
    selector: 'my-app',
    templateUrl: "./app/todo-list.component.html",
    providers: [TodoService],
    pipes: [ TodosSortPipe ]

})

パイプコード:

import { Pipe } from "angular2/core";
import {Todo} from './todo';

@Pipe({
  name: "sort"
})
export class TodosSortPipe {
  transform(array: Array<Todo>, args: string): Array<Todo> {
    array.sort((a: any, b: any) => {
      if (a < b) {
        return -1;
      } else if (a > b) {
        return 1;
      } else {
        return 0;
      }
    });
    return array;
  }
}

Todoプロパティで並べ替えられたの配列をソートしようとしていますcompleted。最初にtodo.completed = falseそして次にtodo.complete = true

transformメソッドとそのメソッドとメソッドで引数を渡す方法がよくわかりませんsort

args: string議論は何ですか?何であるab、彼らはどこから来るの?


私は+ Angular5で[並べ替えのために、このモジュールのパッケージを発見したバージョンがfreakyjolly.com/...
コードスパイ

回答:


78

@Thierry Templierの応答を変更して、パイプがカスタムオブジェクトを角度4でソートできるようにしました。

import { Pipe, PipeTransform } from "@angular/core";

@Pipe({
  name: "sort"
})
export class ArraySortPipe  implements PipeTransform {
  transform(array: any, field: string): any[] {
    if (!Array.isArray(array)) {
      return;
    }
    array.sort((a: any, b: any) => {
      if (a[field] < b[field]) {
        return -1;
      } else if (a[field] > b[field]) {
        return 1;
      } else {
        return 0;
      }
    });
    return array;
  }
}

そしてそれを使うには:

*ngFor="let myObj of myArr | sort:'fieldName'"

うまくいけば、これは誰かを助けます。


1
メッセージがあります:The pipe 'sort' could not be found。角度のある2つのパイプのように、コンポーネントにパイプを注入することはできますか?
MatijaŽupančić2017

アプリコンポーネントにパイプを挿入する方法については、@ Thierry Templierの応答を参照してください
Sal

モジュールの階層宣言に「ArraySortPipe」を含める必要があります。次のようなものです:import {ArraySortPipe} from './../../shared/filters.pipe'; 「app.module.ts」とその下のモジュール。put:宣言:[ArraySortPipe]
Dudi

71

詳細については、https://angular.io/guide/pipes#appendix-no-filterpipe-or-orderbypipeをご覧ください。この引用が最も関連性があります。基本的に、積極的に縮小する必要がある大規模なアプリの場合、フィルタリングと並べ替えのロジックはコンポーネント自体に移動する必要があります。

「私たちの中には、これを積極的に縮小することを気にしない人もいます。それが私たちの選択です。しかし、Angular製品は他の誰かが積極的に縮小することを妨げるべきではありません。

Angularチームと経験豊富なAngular開発者の多くは、フィルタリングとソートのロジックをコンポーネント自体に移動することを強くお勧めします。コンポーネントは、filteredHeroesプロパティまたはsortedHeroesプロパティを公開し、サポートロジックを実行するタイミングと頻度を制御できます。パイプに入れてアプリ全体で共有する機能は、フィルタリング/並べ替えサービスに記述してコンポーネントに注入できます。」


7
「サポートするロジックを実行するタイミングと頻度を制御」できる方法で、ロジックを「コンポーネント自体に」どのように移動する必要がありますか?これに従う良い例はありますか?
Mzzzzzz 2017年

1
@Mzzzzzz filteredHeroesandのようなプロパティについて言及している場合sortedHeroes、コンポーネントを初期化するときに、並べ替え/フィルタリングロジックを実行し(多分ngOnInitからメソッドを呼び出す)、そのプロパティを並べ替え/フィルタリングされた結果で設定し、ロジックを再実行するか、必要をトリガーするものがある場合にのみプロパティを更新します(たとえば、ユーザーインタラクションがAJAX呼び出しをトリガーしてより多くのヒーローを取得するか、ユーザーがチェックボックスをクリックしていくつかの基準に基づいてそれらの半分をフィルターで
除外する

41

sort配列のメソッドを活用する、このためのカスタムパイプを実装できます。

import { Pipe } from "angular2/core";

@Pipe({
  name: "sort"
})
export class ArraySortPipe {
  transform(array: Array<string>, args: string): Array<string> {
    array.sort((a: any, b: any) => {
      if (a < b) {
        return -1;
      } else if (a > b) {
        return 1;
      } else {
        return 0;
      }
    });
    return array;
  }
}

そして、次に説明するようにこのパイプを使用します。pipesコンポーネントの属性にパイプを指定することを忘れないでください:

@Component({
  (...)
  template: `
    <li *ngFor="list | sort"> (...) </li>
  `,
  pipes: [ ArraySortPipe ]
})
(...)

これは、文字列値を持つ配列の単純なサンプルですが、高度な並べ替え処理(オブジェクト配列の場合はオブジェクト属性に基づいて、並べ替えパラメーターに基づいて)を行うことができます。

これはplunkrです:https ://plnkr.co/edit/WbzqDDOqN1oAhvqMkQRQ?p=preview 。

それがあなたを助けることを願っています、ティエリー


1
回答ありがとうございます。並べ替えの方法を説明していただけますか?

1
実際、このsortメソッドはJavaScript Arrayオブジェクトのメソッドです。このリンクを参照してください:developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
ティエリーテンプリエ

OK、わかりました。引数として比較関数を指定したjavascript sortメソッドを使用しています。ありがとうございました!

1
残念ながら、プランカーは非推奨です。ティエリー?

4
pipes: [..]宣言は、もはや有効(もはや必要)ではありません
phil294

9

OrderByPipeを更新:文字列をソートしない問題を修正。

OrderByPipeクラスを作成します。

import { Pipe, PipeTransform } from "@angular/core";
@Pipe( {
name: 'orderBy'
} )
export class OrderByPipe implements PipeTransform {
transform( array: Array<any>, orderField: string, orderType: boolean ): Array<string> {
    array.sort( ( a: any, b: any ) => {
        let ae = a[ orderField ];
        let be = b[ orderField ];
        if ( ae == undefined && be == undefined ) return 0;
        if ( ae == undefined && be != undefined ) return orderType ? 1 : -1;
        if ( ae != undefined && be == undefined ) return orderType ? -1 : 1;
        if ( ae == be ) return 0;
        return orderType ? (ae.toString().toLowerCase() > be.toString().toLowerCase() ? -1 : 1) : (be.toString().toLowerCase() > ae.toString().toLowerCase() ? -1 : 1);
    } );
    return array;
  }
}

あなたのコントローラーで:

@Component({
pipes: [OrderByPipe]
})

またはあなたの

 declarations: [OrderByPipe]

あなたのhtmlで:

<tr *ngFor="let obj of objects | orderBy : ObjFieldName: OrderByType">

ObjFieldName:ソートするオブジェクトフィールド名。

OrderByType:boolean; true:降順。false:昇順。


a [orderField]-b [orderField]を比較する文字列引数の場合、NaNを返します
PiotrPęczekFeb

日付引数の場合は機能しません。テキストとしての日付フォーマットは、誤った順序になります。
ラファエルピサオ

9

Angularには箱から出してすぐにorderByフィルターが付属していませんが、必要な場合は簡単に作成できます。ただし、速度と最小化に関して行う必要があるいくつかの注意点があります。下記参照。

単純なパイプは次のようになります。

import { Pipe, PipeTransform } from '@angular/core';

@Pipe({
  name: 'sort'
})
export class SortPipe implements PipeTransform {
  transform(ary: any, fn: Function = (a,b) => a > b ? 1 : -1): any {
    return ary.sort(fn)
  }
}

このパイプはソート関数(fn)を受け入れ、プリミティブの配列を適切な方法でソートするデフォルト値をパイプに与えます。必要に応じて、このソート関数をオーバーライドするオプションがあります。

属性名は縮小される可能性があるため、属性名を文字列として受け入れません。コードを縮小すると変更されますが、縮小文字はテンプレート文字列の値も縮小できるほどスマートではありません。

プリミティブ(数値と文字列)の並べ替え

これを使用して、デフォルトのコンパレータを使用して数値または文字列の配列をソートできます。

import { Component } from '@angular/core';

@Component({
  selector: 'cat',
  template: `
    {{numbers | sort}}
    {{strings | sort}}
  `
})
export class CatComponent
  numbers:Array<number> = [1,7,5,6]
  stringsArray<string> = ['cats', 'hats', 'caveats']
}

オブジェクトの配列の並べ替え

オブジェクトの配列をソートする場合は、コンパレーター関数を指定できます。

import { Component } from '@angular/core';

@Component({
  selector: 'cat',
  template: `
    {{cats | sort:byName}}
  `
})
export class CatComponent
  cats:Array<Cat> = [
    {name: "Missy"},
    {name: "Squoodles"},
    {name: "Madame Pompadomme"}
  ]
  byName(a,b) {
    return a.name > b.name ? 1 : -1
  }
}

警告-純粋なパイプと不純なパイプ

Angular 2には、純粋なパイプと不純なパイプの概念があります。

純粋なパイプは、オブジェクトIDを使用して変更検出を最適化します。つまり、新しいオブジェクトを配列に追加した場合など、入力オブジェクトがIDを変更した場合にのみ、パイプが実行されます。それはオブジェクトに降下しません。つまり、this.cats[2].name = "Fluffy"たとえばネストされた属性を変更した場合、パイプは再実行されません。これにより、Angularが高速になります。角パイプはデフォルトで純粋です。

一方、不純なパイプはオブジェクトの属性をチェックします。これにより、速度が大幅に低下する可能性があります。パイプ関数が何をするかを保証できないため(たとえば、時刻に基づいて異なる順序でソートされる可能性があります)、非同期イベントが発生するたびに不純なパイプが実行されます。配列が大きい場合、これはアプリをかなり遅くします。

上のパイプは純正です。つまり、配列内のオブジェクトが不変である場合にのみ実行されます。猫を変更する場合は、猫オブジェクト全体を新しい猫オブジェクトに置き換える必要があります。

this.cats[2] = {name:"Tomy"}

pure属性を設定することで、上記を不純なパイプに変更できます。

import { Pipe, PipeTransform } from '@angular/core';

@Pipe({
  name: 'sort',
  pure: false
})
export class SortPipe implements PipeTransform {
  transform(ary: any, fn: Function = (a,b) => a > b ? 1 : -1): any {
    return ary.sort(fn)
  }
}

このパイプはオブジェクトに下降しますが、遅くなります。注意して使用してください。


ありがとう..たくさん助けてくれました。しかし、1つの質問..並べ替えにパイプまたはフィルターを使用するべきではない場合、最良のアプローチは何ですか?私はどこでも検索しましたが、誰もがパイプを作成することで解決策を提供しています。
Pavan Shukla

@PavanShuklaパイプを使用できます。配列のエントリが不変であることを確認し、純粋なパイプを作成してください。または、大きな配列がない場合は、不純なパイプを作成し、各レンダリングを並べ替えます。または、コンポーネントの属性としてソートされた配列を作成し、それをレンダリングします。
superluminary

各cloumn見出しをクリックするときにarray.sortロジックを使用しました。表示データ配列に対してこの操作を行っています。それは良い方法ですか?
Pavan Shukla

7

必要なことだけを行うOrderByパイプを作成しました。オブジェクトの列挙可能なオブジェクトの複数の列でソートできることもサポートしています。

<li *ngFor="#todo in todos | orderBy : ['completed']">{{todo.name}} {{todo.completed}}</li>

このパイプは、ページのレンダリング後に配列にさらに項目を追加することを可能にし、更新で配列を動的にソートします。

私はここにプロセスについて書いています

そして、これが実際のデモです:http : //fuelinteractive.github.io/fuel-ui/#/pipe/orderby and https://plnkr.co/edit/DHLVc0?p=info


null値を処理していません。
Ali Habibzadeh 2016

if(a == null)a = 0; if(b == null)b = 0;
Ali Habibzadeh 2016

また、同じ値の値はびくびくし、インターフェイスでクリックすると動きます
Ali Habibzadeh

@XGreenこれをありがとう。次のfuel-uiのアップデートで、null /未定義の値のサポートを追加します。等しい値の急激さについては、私はこれを見ていません。どのブラウザを使用していますか?
Cory Shaw

Chromeバージョン50.0.2661.86(64ビット)、OSX El Capitan
Ali Habibzadeh 2016

4

アンギュラーでロダッシュを使用することをお勧めします、次にあなたのパイプは次のようになります:

import {Pipe, PipeTransform} from '@angular/core';
import * as _ from 'lodash'
@Pipe({
    name: 'orderBy'
})
export class OrderByPipe implements PipeTransform {

    transform(array: Array<any>, args?: any): any {
        return _.sortBy(array, [args]);
    }

}

のようにhtmlで使用してください

*ngFor = "#todo of todos | orderBy:'completed'"

モジュールにパイプを追加することを忘れないでください

@NgModule({
    ...,
    declarations: [OrderByPipe, ...],
    ...
})

私はあなたのアプローチlikeлександрПетрикが好きですが、テンプレートで配列を送信することを好みます:orderBy:['field1'、 'field2']そしてパイプを呼び出します:return _.sortBy(array、args);
Eric

1
_.sortByを使用する際の問題は、子孫の順序を指定できないことです。_.orderByを使用すると、すべてのフィールドにカスタムの順序を指定できることがわかりました。すなわち:_.orderBy(array、['field1'、 'field2']、['asc'、 'desc'])
Eric

3

これは、渡したすべてのフィールドで機能します。(重要:アルファベット順のみなので、日付を渡すと、日付ではなくアルファベット順で並べられます)

/*
 *      Example use
 *      Basic Array of single type: *ngFor="let todo of todoService.todos | orderBy : '-'"
 *      Multidimensional Array Sort on single column: *ngFor="let todo of todoService.todos | orderBy : ['-status']"
 *      Multidimensional Array Sort on multiple columns: *ngFor="let todo of todoService.todos | orderBy : ['status', '-title']"
 */

import {Pipe, PipeTransform} from "@angular/core";

@Pipe({name: "orderBy", pure: false})
export class OrderByPipe implements PipeTransform {

    value: string[] = [];

    static _orderByComparator(a: any, b: any): number {

        if (a === null || typeof a === "undefined") { a = 0; }
        if (b === null || typeof b === "undefined") { b = 0; }

        if (
            (isNaN(parseFloat(a)) ||
            !isFinite(a)) ||
            (isNaN(parseFloat(b)) || !isFinite(b))
        ) {
            // Isn"t a number so lowercase the string to properly compare
            a = a.toString();
            b = b.toString();
            if (a.toLowerCase() < b.toLowerCase()) { return -1; }
            if (a.toLowerCase() > b.toLowerCase()) { return 1; }
        } else {
            // Parse strings as numbers to compare properly
            if (parseFloat(a) < parseFloat(b)) { return -1; }
            if (parseFloat(a) > parseFloat(b)) { return 1; }
        }

        return 0; // equal each other
    }

    public transform(input: any, config = "+"): any {
        if (!input) { return input; }

        // make a copy of the input"s reference
        this.value = [...input];
        let value = this.value;
        if (!Array.isArray(value)) { return value; }

        if (!Array.isArray(config) || (Array.isArray(config) && config.length === 1)) {
            let propertyToCheck: string = !Array.isArray(config) ? config : config[0];
            let desc = propertyToCheck.substr(0, 1) === "-";

            // Basic array
            if (!propertyToCheck || propertyToCheck === "-" || propertyToCheck === "+") {
                return !desc ? value.sort() : value.sort().reverse();
            } else {
                let property: string = propertyToCheck.substr(0, 1) === "+" || propertyToCheck.substr(0, 1) === "-"
                    ? propertyToCheck.substr(1)
                    : propertyToCheck;

                return value.sort(function(a: any, b: any) {
                    let aValue = a[property];
                    let bValue = b[property];

                    let propertySplit = property.split(".");

                    if (typeof aValue === "undefined" && typeof bValue === "undefined" && propertySplit.length > 1) {
                        aValue = a;
                        bValue = b;
                        for (let j = 0; j < propertySplit.length; j++) {
                            aValue = aValue[propertySplit[j]];
                            bValue = bValue[propertySplit[j]];
                        }
                    }

                    return !desc
                        ? OrderByPipe._orderByComparator(aValue, bValue)
                        : -OrderByPipe._orderByComparator(aValue, bValue);
                });
            }
        } else {
            // Loop over property of the array in order and sort
            return value.sort(function(a: any, b: any) {
                for (let i = 0; i < config.length; i++) {
                    let desc = config[i].substr(0, 1) === "-";
                    let property = config[i].substr(0, 1) === "+" || config[i].substr(0, 1) === "-"
                        ? config[i].substr(1)
                        : config[i];

                    let aValue = a[property];
                    let bValue = b[property];

                    let propertySplit = property.split(".");

                    if (typeof aValue === "undefined" && typeof bValue === "undefined" && propertySplit.length > 1) {
                        aValue = a;
                        bValue = b;
                        for (let j = 0; j < propertySplit.length; j++) {
                            aValue = aValue[propertySplit[j]];
                            bValue = bValue[propertySplit[j]];
                        }
                    }

                    let comparison = !desc
                        ? OrderByPipe._orderByComparator(aValue, bValue)
                        : -OrderByPipe._orderByComparator(aValue, bValue);

                    // Don"t return 0 yet in case of needing to sort by next property
                    if (comparison !== 0) { return comparison; }
                }

                return 0; // equal each other
            });
        }
    }
}

使用例を投稿できますか?
TheUnreal 2016年

あなたが提供したコードをコンパイルできません。プロパティ@Componentがないというエラーが表示されpipesます。
アジマス2018年

3

これは、AngularJs orderby pipe for angular 4の良い置き換えです。使い方は簡単でシンプル。

これは詳細についてはgithub URLです https://github.com/VadimDez/ngx-order-pipe

import { Pipe, PipeTransform } from '@angular/core';

@Pipe({
  name: 'orderBy'
})
export class OrderPipe implements PipeTransform {

  transform(value: any | any[], expression?: any, reverse?: boolean): any {
    if (!value) {
      return value;
    }

    const isArray = value instanceof Array;

    if (isArray) {
      return this.sortArray(value, expression, reverse);
    }

    if (typeof value === 'object') {
      return this.transformObject(value, expression, reverse);
    }

    return value;
  }

  /**
   * Sort array
   *
   * @param value
   * @param expression
   * @param reverse
   * @returns {any[]}
   */
  private sortArray(value: any[], expression?: any, reverse?: boolean): any[] {
    const isDeepLink = expression && expression.indexOf('.') !== -1;

    if (isDeepLink) {
      expression = OrderPipe.parseExpression(expression);
    }

    let array: any[] = value.sort((a: any, b: any): number => {
      if (!expression) {
        return a > b ? 1 : -1;
      }

      if (!isDeepLink) {
        return a[expression] > b[expression] ? 1 : -1;
      }

      return OrderPipe.getValue(a, expression) > OrderPipe.getValue(b, expression) ? 1 : -1;
    });

    if (reverse) {
      return array.reverse();
    }

    return array;
  }


  /**
   * Transform Object
   *
   * @param value
   * @param expression
   * @param reverse
   * @returns {any[]}
   */
  private transformObject(value: any | any[], expression?: any, reverse?: boolean): any {
    let parsedExpression = OrderPipe.parseExpression(expression);
    let lastPredicate = parsedExpression.pop();
    let oldValue = OrderPipe.getValue(value, parsedExpression);

    if (!(oldValue instanceof Array)) {
      parsedExpression.push(lastPredicate);
      lastPredicate = null;
      oldValue = OrderPipe.getValue(value, parsedExpression);
    }

    if (!oldValue) {
      return value;
    }

    const newValue = this.transform(oldValue, lastPredicate, reverse);
    OrderPipe.setValue(value, newValue, parsedExpression);
    return value;
  }

  /**
   * Parse expression, split into items
   * @param expression
   * @returns {string[]}
   */
  private static parseExpression(expression: string): string[] {
    expression = expression.replace(/\[(\w+)\]/g, '.$1');
    expression = expression.replace(/^\./, '');
    return expression.split('.');
  }

  /**
   * Get value by expression
   *
   * @param object
   * @param expression
   * @returns {any}
   */
  private static getValue(object: any, expression: string[]) {
    for (let i = 0, n = expression.length; i < n; ++i) {
      const k = expression[i];
      if (!(k in object)) {
        return;
      }
      object = object[k];
    }

    return object;
  }

  /**
   * Set value by expression
   *
   * @param object
   * @param value
   * @param expression
   */
  private static setValue(object: any, value: any, expression: string[]) {
    let i;
    for (i = 0; i < expression.length - 1; i++) {
      object = object[expression[i]];
    }

    object[expression[i]] = value;
  }
}

2

フィルターと注文方法はANGULAR 2から削除されており、独自に作成する必要があることがわかっているため、plunker詳細な記事の良い例を以下に示します

フィルターとorderbyの両方を使用しました、これは注文パイプのコードです

import { Pipe, PipeTransform } from '@angular/core';    
@Pipe({  name: 'orderBy' })
export class OrderrByPipe implements PipeTransform {

  transform(records: Array<any>, args?: any): any {       
    return records.sort(function(a, b){
          if(a[args.property] < b[args.property]){
            return -1 * args.direction;
          }
          else if( a[args.property] > b[args.property]){
            return 1 * args.direction;
          }
          else{
            return 0;
          }
        });
    };
 }

2

これをオブジェクトに使用できます。

@Pipe({
  name: 'sort',
})
export class SortPipe implements PipeTransform {

  transform(array: any[], field: string): any[] {
    return array.sort((a, b) => a[field].toLowerCase() !== b[field].toLowerCase() ? a[field].toLowerCase() < b[field].toLowerCase() ? -1 : 1 : 0);
  }

}

2

package.jsonに、次のようなものを追加します(このバージョンはAngular 2では問題ありません)。

  "ngx-order-pipe": "^1.1.3",

あなたのtypescriptモジュールで(そしてインポート配列):

  import { OrderModule } from 'ngx-order-pipe';

1
<!-- const cars=['Audi','Merc','BMW','Volvo','Tesla'] -->

<ul>
  <li *ngFor="let car of cars">{{car}}</li>
</ul>


/*
 *ngFor="let c of oneDimArray | sortBy:'asc'"
 *ngFor="let c of arrayOfObjects | sortBy:'asc':'propertyName'"
*/
import { Pipe, PipeTransform } from '@angular/core';
import { orderBy } from 'lodash';

@Pipe({ name: 'sortBy' })
export class SortByPipe implements PipeTransform {

  transform(value: any[], order = '', column: string = ''): any[] {
    if (!value || order === '' || !order) { return value; } // no array
    if (!column || column === '') { return sortBy(value); } // sort 1d array
    if (value.length <= 1) { return value; } // array with only one item
    return orderBy(value, [column], [order]);
  }
}

1
ありがとう、すばらしい答え
AM-EVS

0

Angular2の現在のバージョンでは、orderByおよびArraySortパイプはサポートされていません。これを行うには、いくつかのカスタムパイプを作成/使用する必要があります。


0

Angular 5+バージョンでは、ngx-order-pipeパッケージを使用できます

ソースチュートリアルリンク

パッケージをインストールする

$ npm install ngx-order-pipe --save

アプリモジュールにインポート

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';

import { FormsModule } from '@angular/forms';
import { AppComponent } from './app.component';
import { OrderModule } from 'ngx-order-pipe';

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    FormsModule,
    OrderModule
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

どこでも使う

  <ul>
    <li *ngFor="let item of (dummyData | orderBy:'name') ">
      {{item.name}}
    </li>
  </ul>


-1
Component template:
todos| sort: ‘property’:’asc|desc’

Pipe code:

import { Pipe,PipeTransform  } from "angular/core";
import {Todo} from './todo';

@Pipe({
  name: "sort"
})
export class TodosSortPipe implements PipeTransform {
  transform(array: Array<Todo>, args: string): Array<Todo> {
    array.sort((a: any, b: any) => {
      if (a < b) {
        return -1;
      } else if (a > b) {
        return 1;
      } else {`enter code here`
        return 0;
      }
    });
    return array;
  }
}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.