Verification: a143cc29221c9be0

Php array filter with keys

◆ __construct()

ConditionTree constructor.

См. определение в файле conditiontree.php строка 51

52  {

53  $this->logic = static::LOGIC_AND;

54  }

logic($logic=null)

All conditions will be imploded by this logic: static::LOGIC_AND or static::LOGIC_OR.

◆ __clone()

См. определение в файле conditiontree.php строка 683

684  {

685  $newConditions = array();

686 

687  foreach ($this->conditions as $condition)

688  {

689  $newConditions[] = clone $condition;

690  }

691 

692  $this->conditions = $newConditions;

693  }

◆ addCondition()

addCondition (   $condition )

Adds prepared condition.

Аргументы
Возвращает
$this
Исключения

См. определение в файле conditiontree.php строка 544

545  {

546  if ($condition instanceof Condition || $condition instanceof ConditionTree)

547  {

548  $this->conditions[] = $condition;

549  return $this;

550  }

551 

552  throw new ArgumentException('Unknown type of condition '.gettype($condition));

553  }

◆ convertValue()

convertValue (   $value,
IReadable  $field = null 
)
protected

Converts any value to raw SQL, except of NULL, which is supposed to be handled in Operator.

Аргументы
mixed $value
IReadable $field
Возвращает
mixed|null|string
Исключения

См. определение в файле conditiontree.php строка 626

627  {

628 

629  if ($value instanceof SqlExpression)

630  {

631  return $value->compile();

632  }

633 

634 

635  if ($value instanceof Query)

636  {

637  return $value->getQuery();

638  }

639 

640 

641  if ($value instanceof ConditionTree)

642  {

643  return $value->getSql($this->chains);

644  }

645 

646 

647  if ($value === null)

648  {

649  return new Expressions\NullExpression;

650  }

651 

652  if ($value instanceof Expressions\ColumnExpression)

653  {

654 

655  $valueChain = $this->chains[$value->getDefinition()];

656  return $valueChain->getSqlDefinition();

657  }

658 

659  return $field->convertValueToDb($value);

660  }

◆ convertValues()

convertValues (   $values,
IReadable  $field = null 
)
protected

Converts array of values to raw SQL.

См. также
ConditionTree::convertValue()
Аргументы
array $values
\Bitrix\Main\ORM\Fields\IReadable | null $field
Возвращает
array
Исключения

См. определение в файле conditiontree.php строка 673

674  {

675  foreach ($values as $k => $value)

676  {

677  $values[$k] = $this->convertValue($value, $field);

678  }

679 

680  return $values;

681  }

convertValue($value, IReadable $field=null)

Converts any value to raw SQL, except of NULL, which is supposed to be handled in Operator.

◆ createFromArray()

static createFromArray (   $filter )
static

Creates filter object from array.

Аргументы
Возвращает
ConditionTree
Исключения

См. определение в файле conditiontree.php строка 703

704  {

706 

707  if (isset($filter['logic']))

708  {

709  $conditionTree->logic($filter['logic']);

710  unset($filter['logic']);

711  }

712 

713  if (isset($filter['negative']))

714  {

715  $conditionTree->negative($filter['negative']);

716  unset($filter['negative']);

717  }

718 

719  foreach ($filter as $condition)

720  {

721  if (isset($condition[0]) && is_array($condition[0]))

722  {

723  $conditionTree->where(static::createFromArray($condition));

724  }

725  else

726  {

727 

728  $valueKey = key(array_reverse($condition, true));

729  $valueElement = $condition[$valueKey];

730 

731  if (is_array($valueElement))

732  {

733  if (isset($valueElement['value']))

734  {

735  $value = $valueElement['value'];

736  }

737  elseif (isset($valueElement['column']))

738  {

739  $value = new ColumnExpression($valueElement['column']);

740  }

741  else

742  {

743 

744  foreach ($valueElement as $k => $singleValue)

745  {

746  if (is_array($singleValue))

747  {

748  if (isset($singleValue['value']))

749  {

750  $valueElement[$k] = $singleValue['value'];

751  }

752  elseif (isset($singleValue['column']))

753  {

754  $valueElement[$k] = new ColumnExpression($singleValue['column']);

755  }

756  }

757  }

758 

759  $value = $valueElement;

760  }

761 

762  $condition[$valueKey] = $value;

763  }

764 

765  $conditionTree->where(...$condition);

766  }

767  }

768 

769  return $conditionTree;

770  }

static filter()

Returns new instance of Filter.

◆ getConditions()

◆ getSql()

Returns SQL for all conditions and subfilters.

Аргументы
Возвращает
string
Исключения

См. определение в файле conditiontree.php строка 444

445  {

446 

447  $this->chains = $chains;

448 

449  $finalSql = array();

450 

451 

452  foreach ($this->conditions as $condition)

453  {

454  if ($condition instanceof ConditionTree)

455  {

456 

457  $subFilter = $condition;

458  $sql = $subFilter->getSql($chains);

459 

460  if (count($subFilter->getConditions()) > 1)

461  {

462  $sql = "({$sql})";

463  }

464  }

465  else

466  {

467 

468  $columnSqlDefinition = null;

469  $columnField = null;

470 

471 

472  if ($condition->getColumn() !== null)

473  {

474  $chain = $chains[$condition->getDefinition()];

475  $columnSqlDefinition = $chain->getSqlDefinition();

476 

477 

478  $columnField = $chain->getLastElement()->getValue();

479  }

480 

481 

482  if (in_array($condition->getOperator(), array('in', 'between'), true) && is_array($condition->getValue()))

483  {

484 

485  $finalValue = $this->convertValues($condition->getValue(), $columnField);

486  }

487  else

488  {

489  $finalValue = $this->convertValue($condition->getValue(), $columnField);

490  }

491 

492 

494  $operator = $operators[$condition->getOperator()];

495 

496 

497  $sql = call_user_func(

498  array('Bitrix\Main\ORM\Query\Filter\Operator', $operator),

499  $columnSqlDefinition, $finalValue

500  );

501  }

502 

503  if ($sql != '')

504  {

505  $finalSql[] = $sql;

506  }

507  }

508 

509  $sql = null;

510 

511  if (!empty($finalSql))

512  {

513 

514  $sql = join(" ".strtoupper($this->logic)." ", $finalSql);

515 

516 

517  if ($this->isNegative)

518  {

519  $sql = count($finalSql) > 1 ? "NOT ({$sql})" : "NOT {$sql}";

520  }

521  }

522 

523  return $sql;

524  }

convertValues($values, IReadable $field=null)

Converts array of values to raw SQL.

static get()

List of available operators code => method.

◆ hasConditions()

Checks if filter is not empty.

Возвращает
bool

См. определение в файле conditiontree.php строка 560

561  {

562  return !empty($this->conditions);

563  }

◆ logic()

All conditions will be imploded by this logic: static::LOGIC_AND or static::LOGIC_OR.

Аргументы
Возвращает
$this|string
Исключения

См. определение в файле conditiontree.php строка 64

65  {

67  {

69  }

70 

71  if (!in_array(strtolower($logic), [static::LOGIC_AND, static::LOGIC_OR], true))

72  {

73  throw new ArgumentException("Unknown logic");

74  }

75 

77 

78  return $this;

79  }

◆ negative()

negative (   $negative = true )

Sets NOT before all the conditions.

Аргументы
Возвращает
$this

См. определение в файле conditiontree.php строка 88

89  {

90  $this->isNegative = (bool) $negative;

91  return $this;

92  }

◆ removeAllConditions()

Removes all conditions.

См. определение в файле conditiontree.php строка 611

612  {

613  $this->conditions = [];

614  }

◆ removeCondition()

removeCondition (   $condition )

Removes one condition.

Аргументы
Возвращает
bool

См. определение в файле conditiontree.php строка 594

595  {

596  foreach ($this->conditions as $k => $_condition)

597  {

598  if ($condition === $_condition)

599  {

600  unset($this->conditions[$k]);

601  return true;

602  }

603  }

604 

605  return false;

606  }

◆ replaceCondition()

replaceCondition (   $currentCondition,
  $newCondition 
)

Replaces condition with a new one.

Аргументы
$currentCondition
$newCondition
Возвращает
bool

См. определение в файле conditiontree.php строка 573

574  {

575  foreach ($this->conditions as $k => $condition)

576  {

577  if ($condition === $currentCondition)

578  {

579  $this->conditions[$k] = $newCondition;

580  return true;

581  }

582  }

583 

584  return false;

585  }

◆ where()

General condition.

In regular case used with 3 parameters: where(columnName, operator, value), e.g. ('ID', '=', 1); ('SALARY', '>', '500')

List of available operators can be found in Operator class.

См. также
Operator::$operators

Can be used in short format: where(columnName, value), with operator '=' by default Can be used in ultra short format: where(columnName), for boolean fields only

Can be used for subfilter set: where(ConditionTree subfilter)

Instead of columnName, you can use runtime field: where(new ExpressionField('TMP', 'CONCAT(s, s)', ["NAME", "LAST_NAME"]), 'Anton Ivanov') or with expr helper where(Query::expr()->concat("NAME", "LAST_NAME"), 'Anton Ivanov')

Аргументы
Возвращает
$this
Исключения

См. определение в файле conditiontree.php строка 119

120  {

121  $filter = func_get_args();

122 

123 

124  if (count($filter) == 1 && $filter[0] instanceof ConditionTree)

125  {

126  $this->conditions[] = $filter[0];

127  return $this;

128  }

129 

130 

131  if (count($filter) == 1 && $filter[0] instanceof Condition)

132  {

133  $this->conditions[] = $filter[0];

134  return $this;

135  }

136 

137 

139  {

140  foreach ($filter[0] as $condition)

141  {

142 

143  call_user_func_array(array($this, 'where'), $condition);

144  }

145  return $this;

146  }

147 

148 

149  if (count($filter) == 3)

150  {

151 

152  list($column, $operator, $value) = $filter;

153  }

154  elseif (count($filter) == 2)

155  {

156 

157  list($column, $value) = $filter;

158  $operator = '=';

159  }

160  elseif (count($filter) == 1)

161  {

162 

164  $operator = '=';

165  $value = true;

166  }

167  else

168  {

169  throw new ArgumentException('Wrong arguments');

170  }

171 

172 

174  if (!isset($operators[$operator]))

175  {

176  throw new ArgumentException("Unknown operator `{$operator}`");

177  }

178 

179 

180  $this->conditions[] = new Condition($column, $operator, $value);

181 

182  return $this;

183  }

◆ whereBetween()

whereBetween (   $column,
  $valueMin,
  $valueMax 
)

BETWEEN condition.

Аргументы
$column
$valueMin
$valueMax
Возвращает
$this

См. определение в файле conditiontree.php строка 309

310  {

311  $this->conditions[] = new Condition($column, 'between', array($valueMin, $valueMax));

312 

313  return $this;

314  }

◆ whereColumn()

The same logic as where(), but value will be taken as another column name.

См. также
ConditionTree::where()
Аргументы
Возвращает
$this
Исключения

См. определение в файле conditiontree.php строка 213

214  {

215  $filter = func_get_args();

216 

217  if (count($filter) == 3)

218  {

219  list($column, $operator, $value) = $filter;

220  }

221  elseif (count($filter) == 2)

222  {

223  list($column, $value) = $filter;

224  $operator = '=';

225  }

226  else

227  {

228  throw new ArgumentException('Wrong arguments');

229  }

230 

231 

232  $value = new Expressions\ColumnExpression($value);

233 

234 

235  $this->where($column, $operator, $value);

236 

237  return $this;

238  }

where()

General condition.

◆ whereExists()

Exists() condition.

Can be used with Query object or plain sql wrapped with SqlExpression.

Аргументы
Query | SqlExpression $query
Возвращает
$this

См. определение в файле conditiontree.php строка 373

374  {

375  $this->conditions[] = new Condition(null, 'exists', $query);

376 

377  return $this;

378  }

◆ whereIn()

whereIn (   $column,
  $values 
)

IN() condition.

Аргументы
string $column
array | Query | SqlExpression $values
Возвращает
$this

См. определение в файле conditiontree.php строка 276

277  {

278  $this->conditions[] = new Condition($column, 'in', $values);

279 

280  return $this;

281  }

◆ whereLike()

whereLike (   $column,
  $value 
)

LIKE condition, without default % placement.

Аргументы
Возвращает
$this

См. определение в файле conditiontree.php строка 342

343  {

344  $this->conditions[] = new Condition($column, 'like', $value);

345 

346  return $this;

347  }

◆ whereMatch()

whereMatch (   $column,
  $value 
)

Fulltext search condition.

См. также
Helper::matchAgainstWildcard() for preparing $value for AGAINST.
Аргументы
Возвращает
$this

См. определение в файле conditiontree.php строка 411

412  {

413  $this->conditions[] = new Condition($column, 'match', $value);

414 

415  return $this;

416  }

◆ whereNot()

Sets NOT before any conditions or subfilter.

См. также
ConditionTree::where()
Аргументы
Возвращает
$this

См. определение в файле conditiontree.php строка 193

194  {

195  $filter = func_get_args();

196 

197  $subFilter = new static();

198  call_user_func_array(array($subFilter, 'where'), $filter);

199 

200  $this->conditions[] = $subFilter->negative();

201  return $this;

202  }

◆ whereNotBetween()

whereNotBetween (   $column,
  $valueMin,
  $valueMax 
)

Negative BETWEEN condition.

См. также
ConditionTree::whereBetween()
Аргументы
$column
$valueMin
$valueMax
Возвращает
$this

См. определение в файле conditiontree.php строка 326

327  {

328  $subFilter = new static();

329  $this->conditions[] = $subFilter->whereBetween($column, $valueMin, $valueMax)->negative();

330 

331  return $this;

332  }

◆ whereNotExists()

whereNotExists (   $query )

Negative Exists() condition.

Can be used with Query object or plain sql wrapped with SqlExpression.

См. также
ConditionTree::whereExists()
Аргументы
Query | SqlExpression $query
Возвращает
$this
Исключения

См. определение в файле conditiontree.php строка 389

390  {

391  if ($query instanceof Query || $query instanceof SqlExpression)

392  {

393  $subFilter = new static();

394  $this->conditions[] = $subFilter->whereExists($query)->negative();

395 

396  return $this;

397  }

398 

399  throw new ArgumentException('Unknown type of query '.gettype($query));

400  }

◆ whereNotIn()

whereNotIn (   $column,
  $values 
)

Negative IN() condition.

См. также
ConditionTree::whereIn()
Аргументы
string $column
array | Query | SqlExpression $values
Возвращает
$this

См. определение в файле conditiontree.php строка 292

293  {

294  $subFilter = new static();

295  $this->conditions[] = $subFilter->whereIn($column, $values)->negative();

296 

297  return $this;

298  }

◆ whereNotLike()

whereNotLike (   $column,
  $value 
)

Negative LIKE condition, without default % placement.

См. также
ConditionTree::whereLike()
Аргументы
Возвращает
$this

См. определение в файле conditiontree.php строка 358

359  {

360  $subFilter = new static();

361  $this->conditions[] = $subFilter->whereLike($column, $value)->negative();

362 

363  return $this;

364  }

◆ whereNotMatch()

whereNotMatch (   $column,
  $value 
)

Negative fulltext search condition.

См. также
Helper::matchAgainstWildcard() for preparing $value for AGAINST.
Аргументы
Возвращает
$this

См. определение в файле conditiontree.php строка 427

428  {

429  $subFilter = new static();

430  $this->conditions[] = $subFilter->whereMatch($column, $value)->negative();

431 

432  return $this;

433  }

◆ whereNotNull()

whereNotNull (   $column )

Compares column with NOT NULL.

Аргументы
Возвращает
$this

См. определение в файле conditiontree.php строка 261

262  {

263  $this->conditions[] = new Condition($column, '', null);

264 

265  return $this;

266  }

◆ whereNull()

Compares column with NULL.

Аргументы
Возвращает
$this

См. определение в файле conditiontree.php строка 247

248  {

249  $this->conditions[] = new Condition($column, '=', null);

250 

251  return $this;

252  }

◆ $chains

◆ $conditions

◆ $isNegative

◆ $logic

◆ LOGIC_AND

all()

Класс коллекции Laravel имеет protected свойство $items, которое содержит массив со всеми данными. Коллекции предоставляют дополнительные методы для работы с этим массивом. Но если вам просто нужен массив без всех этих наворотов, то для этого есть метод!

$emails = collect([
  'abc@gmail.com',
  'user@yahoo.com',
  'example@example.com',
  'test@yahoo.co.in'
]);
$emails_array = $emails->all();
dd($emails_array);
 
/*
Array:4 [▼
  0 => "abc@gmail.com"
  1 => "user@yahoo.com"
  2 => "example@example.com"
  3 => "test@yahoo.co.in"
]
*/

avg()

Этот метод возвращает среднее значение. По умолчанию, он будет вычислять среднее значение из всех значений в коллекции. Но если коллекция содержит пару key => value, то вы можете предоставить ключ функции, и она автоматически вычислит среднее всех значений для этого ключа.

$simple_collection = collect([2, 5, 7, 35, 25, 10]);
$s_avg = $simplex_collection->avg();
// 14

$key_collection = collect(['score' => 98], ['score' => 90], ['score' => 70],['score' => 86]);
$key_avg = $key_collection->avg();
// 86

each()

Метод each() аналогичен функции map для массивов в PHP (array_map()) и JavaScript (метод .map()). Метод берет каждый элемент из коллекции и применяет к нему коллбек (функцию обратного вызова). Этот метод может быть использован для выполнения какой-то операции для каждого элемента, модификации элемента и т. д.

$collection = collect([1, 2, 3, 4]);
$collection->each(function($item){ 
    return $item * $item;
});
// [1,4,9,16]

chunk()

Метод chunk() используется для разделения коллекции на несколько блоков заданного размера.

$users = User::all();
$userschunk = $users->chunk(2);
dd($userschunk->toArray());

array:3 [▼
  0 => array:2 [▼
    0 => array:3 [▼
      "id" => 1
      "name" => "John Doe"
      "email" => "johndoe@example.com"
    ]
    1 => array:3 [▼
      "id" => 2
      "name" => "Jack Halt"
      "email" => "jhalt@example.com"
    ]
  ]
  1 => array:1 [▼
    2 => array:3 [▼
      "id" => 3
      "name" => "Sam Pitt"
      "email" => "spitt@example.com"
    ]
  ]
]

contains()

Зачастую вам нужно проверить, содержит ли коллекция значение или нет. Laravel Collection предоставляет простой способ сделать это.

Функция contains() используется для проверки того, содержит ли коллекция Laravel значение, переданное ей в качестве параметра. Он вернет логическое значение true, если оно содержится, и false, если нет.

$users = collect(['name' => 'John Doe', 'email' => 'johndoe@example.com']);
$users->contains('johndoe@example.com');
// true

$users->contains('spitt@example.com');
// false

Он также может принимать пару key => value для более детального поиска. Он будет проверять, существует ли данная пара или нет.

$users = collect(['name' => 'John Doe', 'email' => 'johndoe@example.com']);
$users->contains('email', 'johndoe@example.com'); 
// true 

$users->contains('name', 'johndoe@example.com'); 
// false

Вы также можете передать функцию обратного вызова с вашим собственным условием, чтобы проверить, проходит ли какое-либо значение заданное условие.

$collection = collect([11, 25, 30, 45, 50]);
$collection->contains(function ($value, $key) {
    return $value == 55;
});
// false

Метод contains() будет использовать обычное сравнение для применения условия. Для более строгого сравнения можно использовать метод containsStrict().

count() и countBy()

Это очень простой, но очень полезный метод, предоставляемый Laravel Collection. Сколько раз вам нужно подсчитать элементы в коллекции Laravel или массиве? Метод сount() возвращает общее количество элементов в коллекции.

$collection = collect([10,20,30,40,50]);
$collection->count();
// 5

Laravel Collection предоставляет и более совершенный метод, чтобы посчитать его элементы.

Метод countBy() возвращает в виде массив количество вхождений элемента в заданную коллекцию Laravel.

$numbercollection = collect([10, 30,30, 50, 50]);
$counts = $numbercollection->countBy();
$counts->all();
// [10 => 1, 30 => 2, 50 => 2]

filter()

Метод filter() — один из самых популярных и полезных методов Laravel Collection. Он позволяет фильтровать вашу коллекцию с помощью переданной функции обратного вызова. Он возвращает новую коллекцию с отфильтрованными элементами и не изменяет исходную коллекцию.

В функцию обратного вызова передаются ключ и значение в качестве параметров, которые вы можно использовать для создания условия фильтра.

$users = collect(['name' => 'John Doe', 'email' => 'johndoe@example.com']); 
$filter = $users->filter(function($value, $key) {
    if ($value['email'] == 'johndoe@example.com') {
        return true;
    }
});
$filter->all();

/*
[
    1 => [
               'name' => 'John Doe', 
               'email' => 'johndoe@example.com',
     ]
]
*/

Если вы не укажете функции обратного вызова, то он просто удалит все элементы, эквивалентные false. Таким образом, значения, как null, false, '' (пустая строка), 0, [] будут отфильтрованы. Этот метод является самым простым способом отсеять любые пустые элементы в коллекции.

get()

get() — это метод, который возвращает значение в ключе, который вы передаете ему в качестве параметра. Если ключ не передается, то возвращается значение null.

$users = collect(['name' => 'John Doe', 'email' => "johndoe@example.com"]);
$value = $users->get('name');
// John Doe

search()

search() — это еще один небольшой, но полезный метод Laravel Collection. Он ищет в коллекции заданное значение и возвращает его, если он найден. Если он не найден, то будет возвращено значение false.

$numbers = collect([31,21,53,64,27]);
$numbers->search(27);
// 4

groupBy()

Часто вам нужно сгруппировать данные в соответствии с определенными данными. Обычно группировка происходит на уровне базы данных, но все же существует много вариантов использования, в которых вам может потребоваться дополнительно сгруппировать данные в коллекции.

Laravel Collection предлагают удобный метод именно для этого. Он работает аналогично groupBy() коллекций Eloquent и группирует элементы по заданному ключу.

$orders = collect([
  ['product_id' => 'p10', 'email' => 'jdoe@example.com'],
  ['product_id' => 'p10', 'email' => 'billy@example.com'],
  ['product_id' => 'p11', 'email' => 'danny@example.com'],
]);
$grouped = $orders->groupBy('product_id');
$grouped->toArray();

/*
    [
        'p10' => [
            ['product_id' => 'p10', 'email' => 'jdoe@example.com'],
            ['product_id' => 'p10', 'email' => 'billy@example.com'],
        ],
        'p11' => [
            ['product_id' => 'p11', 'email' => 'danny@example.com'],
        ],
    ]
*/

max()

В Excel вы можете использовать эту функцию очень часто, чтобы получить максимальное значение в столбце или строке. Аналогично, Laravel Collections предоставляет функцию max() для получения максимального значения данного ключа среди элементов коллекции.

$counter = collect([['count' => 10], ['count' => 20]]);
$counter->max('count');
// 20

Если вы не передадите какой-либо ключ функции max(), она просто сравнит каждый элемент и вернет больший.

pluck()

pluck() — один из моих любимых и наиболее часто используемых методов для Laravel Collection и частоиспользуемый для Eloquent Collection. Он позволяет нам извлекать значения для данного ключа из коллекции в массив.

$users = collect([
['name' => 'John Doe', 'email' => 'johndoe@example.com'],
['name' => 'Jack Sparrow', 'email' => 'sparrow@example.com']
]);
$emails = $users->pluck('email');

/*
['johndoe@example.com', 'sparrow@example.com']
*/

forget()

forget() — это метод Laravel Collection, который просто удаляет данный ключ и его значение из всех элементов коллекции.

$users = collect(['name' => 'John Doe', 'email' => 'johndoe@example.com']);
$users->forget('name');
$users->all();
// ['email' => 'johndoe@example.com']

toArray()

toArray() — это простой метод Laravel Collection для преобразования объекта коллекции в простой PHP-массив.

$users = collect(['name' => 'John Doe', 'email' => 'johndoe@example.com']);
$users->toArray();

/*
    [
        ['name' => 'John Doe', 'email' => 'johndoe@example.com'],
    ]
*/

Что есть map?

До ES6 разработчики JavaScript использовали объекты для сопоставления ключей со значениями. Однако использование объекта в качестве карты имеет свои ограничения. Например:

  • Не существует надежного способа перебора ключей, и keys()метод преобразует поля в строки, что приводит к конфликту ключей.
  • Нет простого способа добавить новые ключи и значения

ES6 представил несколько новых встроенных классов , включая называемый тип коллекцииMap , который может содержать пары ключ-значение любого типа. В отличие от объектного подхода, новый объект Map может запоминать порядок вставки ключей.

Проще говоря, JavaScript Map- это ассоциативный набор различных ключей и значений. И ключи, и значения могут быть любым примитивом или объектом. Это важная структура данных, которая может быть полезна для многих целей.

Примечание: A WeakMapпохож на Map, но все ключи a WeakMapявляются объектами.

Для создания нового Mapмы используем следующий синтаксис:

let map = new Map([iterable]);

Давайте применим это на практике на более сложном примере. Ниже у нас есть карта, в которой имена являются ключами, а оценки — значениями.

‘use strict’;

//START:DEFINE

const scores =

  new Map([[‘Sara’, 12], [‘Bob’, 11], [‘Jill’, 15], [‘Bruce’, 14]]);

scores.set(‘Jake’, 14);

console.log(scores.size);

//END:DEFINE

  • scores Карта была инициализирована с именами и оценки. Начальные данные могут быть любыми итеративными с парой ключей и значений.
  • Мы добавляем ключ и значение на карту, используя set()метод (строка 7)
  • Чтобы выяснить, сколько ключей в настоящее время находится на карте, мы используем свойство size (строка 9).

Примечание: Map.has(key) выше будет возвращено логическое значение, чтобы указать, находится ли элемент, связанный с указанным ключом, на карте.

Как пользоваться картой

Когда мы узнаем, как создавать карты с помощью JavaScript, мы сможем многое сделать с ними.

Перебирать карты

Во-первых, давайте узнаем об итерации с помощью карт. Мы можем использовать 3 метода:

  • map.keys(): возвращает итерацию для ключей
  • map.entries(): возвращает итерацию для записей [key, value]
  • map.values(): возвращает итерацию для значений

Мы можем перебирать коллекцию ключей и значений с помощью entries()метода, который возвращает итерацию, поэтому мы можем использовать улучшенное for loopвместе с деструктуризацией.

Например, ниже мы извлекаем имя и оценку для каждой пары ключ-значение:

‘use strict’;

//START:DEFINE

const scores =

  new Map([[‘Sara’, 12], [‘Bob’, 11], [‘Jill’, 15], [‘Bruce’, 14]]);

scores.set(‘Jake’, 14);

//END:DEFINE

for(const [name, score] of scores.entries()) {

  console.log(`${name} : ${score}`);

}

Мы также можем использовать forEachметод, который является внутренним итератором.

‘use strict’;

//START:DEFINE

const scores =

  new Map([[‘Sara’, 12], [‘Bob’, 11], [‘Jill’, 15], [‘Bruce’, 14]]);

scores.set(‘Jake’, 14);

//END:DEFINE

scores.forEach((score, name) => console.log(`${name} : ${score}`));

Первый параметр, который получает функция, — это значение ключа, который появляется как второй параметр. Тот же forEach()метод можно использовать для перебора только значений:

‘use strict’;

//START:DEFINE

const scores =

  new Map([[‘Sara’, 12], [‘Bob’, 11], [‘Jill’, 15], [‘Bruce’, 14]]);

scores.set(‘Jake’, 14);

//END:DEFINE

scores.forEach(score => console.log(score));

Если вы получите только один параметр, это будет значение, а если вы получите два параметра, то это будет значение и ключ для каждой пары ключ-значение.

Инициализировать карту с итерируемым объектом

Вы также можете передать конструктору итерируемый объект Map():

let userRoles = new Map([

    [sarah, ‘admin’],

    [bob, ‘editor’],

    [jill, ‘subscriber’]

]);

Получить элемент с карты по ключу

Мы можем получить элементы с карты по ключу с помощью get()метода:

Но если вы передадите ключ, которого нет на этой карте, он вернет undefined.

userRoles.get(sarah); // admin

Но если вы передадите ключ, которого нет на этой карте, он вернет undefined.

let foo = {name: 'Foo'};
userRoles.get(foo); //undefined

Получить количество элементов на карте

Мы можем использовать sizeсвойство, чтобы получить количество элементов на наших картах.

console.log(userRoles.size); // 3

Преобразование ключей или значений карты в массив

Иногда вам может понадобиться работать с массивом вместо итерируемого объекта. Мы можем использовать оператор распространения, чтобы преобразовать ключи для каждого элемента в новый массив.

var keys = [...userRoles.keys()];
console.log(keys);

Этот фрагмент кода преобразует значения элементов в массив:

var roles = [...userRoles.values()];
console.log(roles);

Другие важные методы карты

  • clear(): удаляет элементы из объекта карты.
  • map.set(key, value): сохраняет значение по ключу
  • delete(key): удаляет определенный элемент (указанный ключом)
  • set(key, value): устанавливает значение ключа и возвращает объект карты. Может быть связан с другими методами.
  • forEach(callback[, thisArg]): вызывает обратный вызов для каждой пары «ключ-значение» в порядке вставки. thisArgПараметр является необязательным и устанавливает thisзначение для каждого обратного вызова.
  • has(key): возвращает, trueесли значение, связанное с ключом, существует, в противном случае false.
  • keys(): возвращает новый итератор с ключами для элементов в порядке вставки.
  • values(): возвращает новый объект итератора со значениями для каждого элемента в порядке вставки.
  • map.size: возвращает текущее количество элементов

Что есть set?

Set- еще одна новая коллекция, представленная ES6. ArrayКласс JavaScript может работать с упорядоченным набором данных, но не так хорошо с неупорядоченными коллекциями или когда значения хранятся в коллекции являются уникальными. Вот почему появился JavaScript Set.

A set- это уникальный набор примитивов и объектов, дублирование которых не допускается. Мы можем либо создать пустой набор и добавить объекты, либо инициализировать набор содержимым итерации (например, массива).

Давайте рассмотрим это на примере. Ниже у нас есть набор имен с пятью значениями. Одно из значений не входит в набор из-за дублирования.

‘use strict’;

//START:CREATE

const names = new Set([‘Jack’, ‘Jill’, ‘Jake’, ‘Jack’, ‘Sara’]);

//END:CREATE

//START:SIZE

console.log(names.size);

//END:SIZE

Мы можем добавлять элементы в существующий набор, как показано ниже:

names.add('Matt');

add()Метод возвращает поток Set, который является полезным для цепных операций, таких как более звонков add()или других методов Set:

names.add('Kate')
  .add('Kara');

Как использовать set

Как только мы выясним, как создавать наборы, с ними легко работать. Сначала посмотрим на встроенные функции для наборов:

  • has(): чтобы проверить, есть ли в наборе определенный элемент.
  • clear(): очистить существующий набор или удалить существующий элемент с помощью delete()метода.
  • keys(): получить все значения из набора
  • entries(): для перебора Set с использованием расширенного цикла for, как показано ниже:

‘use strict’;

//START:CREATE

const names = new Set([‘Jack’, ‘Jill’, ‘Jake’, ‘Jack’, ‘Sara’]);

//END:CREATE

//START:ADD

names.add(‘Mike’);

//END:ADD

//START:ADD2

names.add(‘Kate’)

  .add(‘Kara’);

//END:ADD2

console.log(names.has(‘Brad’));

console.log(names.entries());

console.log(names.keys());

console.log(names.values());

//START:ITERATE1

for(const name of names) {

  console.log(name);

}

//END:ITERATE1

filter/ mapс наборами

Set еще не предлагает таких методов, как filter()и map(), но мы можем создать массив из набора и использовать методы функционального стиля для этого нового массива.

Например, ниже мы используем методы filter(), map()и, forEach()чтобы выбрать только имена, начинающиеся с, Jа затем преобразовать их в верхний регистр.

‘use strict’;

//START:CREATE

const names = new Set([‘Jack’, ‘Jill’, ‘Jake’, ‘Jack’, ‘Sara’]);

//END:CREATE

//START:ADD

names.add(‘Mike’);

//END:ADD

//START:ADD2

names.add(‘Kate’)

  .add(‘Kara’);

//END:ADD2

//START:FILTER

[…names].filter(name => name.startsWith(‘J’))

  .map(name => name.toUpperCase())

  .forEach(name => console.log(name));

//END:FILTER

Get the size of a Set

Используйте sizeсвойство объекта Set, чтобы вернуть его размер.

let size = chars.size;
console.log(size);//  3

Удалить элементы из набора

Чтобы удалить элемент из набора, используйте delete()метод.

chars.delete('f');
console.log(chars); // Set {"a", "b", "c", "d", "e"}

А чтобы удалить все элементы набора, используйте clear()метод:

chars.clear();
console.log(chars); // Set{}

Вызов функции обратного вызова для каждого элемента

Чтобы вызвать обратный вызов для каждого элемента вашего набора, используйте forEach()метод.

roles.forEach(role => console.log(role.toUpperCase()));

Другие важные методы Set

  • new Set(iterable): создает набор.
  • set.add(value): добавляет заданное значение и возвращает набор
  • set.has(value): возвращается, trueесли значение существует в наборе, в противном случае возвращается false.
  • set.clear(): удаляет все из набора

Практическое упражнение с map

Чтобы закрепить ваше обучение, давайте выполним практическое упражнение с картой на JavaScript. Используйте Mapдля получения желаемого результата, как указано ниже. При создании объекта createTodo()он должен возвращать элемент карты.

Входные звонки Выход
console.log(todo.get(‘learn JavaScript’)); Выполнено
console.log(todo.get(‘write elegant code’)); работа в процессе
console.log(todo.get(‘automate tests’)); работа в процессе
console.log(completedCount(todo)); 1

Ниже приводится решение этой проблемы. Сначала попробуйте сами.

‘use strict’;

const createTodo = function() {

  const todo = new Map();

  return todo;

};

const completedCount = function(map) {

  return;

};

const todo = createTodo(); //Returns a Map

Разбивка решения

Начнем с создания элемента карты. MapОбъект todoсоздается на линии 4 , используя встроенный класс. Вы можете видеть, что объект карты todoвызывается Map.get()с разными ключами для получения их значений. Это означает, что нам нужно добавить все ключи и значения.

Мы добавляем новый элемент todoс ключами и соответствующими значениями. В строках 5-7 мы добавляем новые элементы, устанавливая значения для ключей.

Для completedCount()мы определяем новую функцию с параметром объекта карты. Функция вернет количество выполненных задач. Итак, по сути, мы фильтруем все значения элементов в объекте карты, чтобы получить элементы со значением, равным done(см. Строку 14).

В строке 15 свойство length используется для подсчета количества специальных элементов.

Инициализация

Чтобы использовать Mongo ODM, создайте соединение Mongo DB. Например:

$mapper = new \DB\Mongo\Mapper(\DB\Mongo $db, string $collection);

Если вы хотите создать класс модели, то:

$f3->set('DB', new \DB\Mongo('mongodb://localhost:27017','fatfree'));
 
class User extends \DB\Mongo\Mapper {
    public function __construct() {
        parent::__construct( \Base::instance()->get('DB'), 'users' );
    }
}
 
$user = new User();
$user->load(array('_id' => new \MongoId('50ecaa466afa2f8c1c000004')));
// etc.

Синтаксис

$ filter

$filter Mongo принимает общий массив Mongo найти, см db.collection.find ссылки и запросы документов учебника.

array([ array $find ]);

Вот простой пример поиска в Mongo:

$userList = $user->find(array('email'=> new \MongoRegex('/gmail/')));
// returns all users with an email address that contains GMAIL
 
// ends with gmail.com => /gmail\.com$/
// starts with john  => /^john/

Или просто загрузите одного пользователя по его ID:

$user->load(array('_id'=> new \MongoId('507c35dd8fada716c89d0013')));

$ option

Аргумент Mongo $option принимает имеет структуру:

array(
    'group' => array (
        'keys',
        'initial',
        'reduce',
        'finalize'
    ),
    'order' => string $order,
    'limit' => integer $limit,
    'offset' => integer $offset
    )
 

Дополнительные сведения о group и order.

Инициализация

Чтобы использовать SQL ODM, создайте соединение SQL DB. Например:

$mapper = new \DB\SQL\Mapper(\DB\SQL $db, string $table [, array|string $fields = NULL [, int $ttl = 60 ]] )
 

Аргумент $fields позволяет указать только те поля , которые нужно отобразить. $fields представляет собой либо массив, либо список (в соответствии с функцией F3 split) имен столбцов, которые необходимо включить в mapper. По умолчанию для всех столбцов.

Когда $ttl! = 0, запускается проверка кэша для предыдущей схемы, и если срок ее действия истек или не найден, текущий результат сохраняется в бэкэнде кэша при условии, что система CACHE включена.

Eсли вы хотите создать класс модели, вы можете завершить его:

$f3->set('DB',new DB\SQL('sqlite:db/database.sqlite'));
 
class User extends \DB\SQL\Mapper {
	public function __construct() {
		parent::__construct( \Base::instance()->get('DB'), 'users' );
	}
}
 
$user = new User();
$user->load('id = 1');
// etc.

Синтаксис

$ filter

Аргумент $filter для SQL принимает следующую структуру:

  • строковое значение для простых строк where

string $whereClause
 
  • значение массива для параметризованных запросов

array ( string $whereClause [, string $bindValue1 [, string $bindValue2 [, ... ]]] )
 

Параметризованные запросы

Рекомендуется использовать параметризованные запросы для всех условий where, которые вводит пользователь.

Пример с параметром в виде вопросительного знака:

$mapper->load(array('username = ? and password = ? and deleted = 0','John','acbd18db4cc2f85cedef654fccc4a4d8'));

И с именованными параметрами:

$mapper->load(array(
	'username = :user and password = :pass and deleted = 0',
	':user'=>'John',':pass'=>'acbd18db4cc2f85cedef654fccc4a4d8'
));

Из-за ограничения PDO нельзя использовать именованный параметр более одного раза в запросе. Вам нужно создать 2 параметра :user1 и :user2 и передать им одинаковое значение.

В одном операторе SQL нельзя использовать и именованные параметры, и вопросительные знаки как параметры; выберите тот или иной вид параметра, но не смешивайте.

Тип данных, определяемый пользователем

Обычно тип данных определяется автоматически, но чтобы значение привязки было определенным типом PDO, используйте следующий синтаксис:

array(
	'prize > :prize and active = 1',
	':prize' => array(123, \PDO::PARAM_INT)
)
 

Когда вы используете оператор LIKE в условии where, обратите внимание, что знак % не входит в критерии where, но входит в параметр привязки следующим образом:

$user->find(array('email LIKE ?','%gmail%')); // returns all users with an email address at GMAIL

Полнотекстовый поиск

Если вы хотите выполнить полнотекстовый поиск ключевых слов по одному или нескольким полям в MySQL, вы можете использовать функцию MATCH AGAINST, которая выглядит так:

$text = 'some text';
$mapper->find(["MATCH (name,code) AGAINST (:search IN BOOLEAN MODE)", ':search' => $text ]);

Если вы также хотите отсортировать результаты по актуальности, вам нужно добавить это выражение соответствия как специальное поле, например:

$mapper->relevance = "MATCH (name,code) AGAINST (:search1 IN BOOLEAN MODE)";
$mapper->find(["MATCH (name,code) AGAINST (:search2 IN BOOLEAN MODE)", ':search1' => $text, ':search2' => $text ], ['order'=>'relevance desc']);

И если вы хотите сопоставить сразу несколько ключевых слов, вам нужно обернуть и экранировать ключевые слова

$mapper->find(["(MATCH(fieldA,fieldB) AGAINST('(".implode('") ("',$keywords).")' IN BOOLEAN MODE )"]);

или вставьте несколько заполнителей:

$mapper->find(["(MATCH(fieldA,fieldB) AGAINST('(?) (?) (?)' IN BOOLEAN MODE )", $a, $b, $c]);

$ option

$option для SQL принимает следующую структуру:

array(
	'order' => string $orderClause,
	'group' => string $groupClause,
	'limit' => integer $limit,
	'offset' => integer $offset
)
 

то есть:

array(
	'order' => 'score DESC, team_name ASC',
	'group' => 'score, player',
	'limit' => 20,
	'offset' => 0
)
 

Цикл each (jQuery.each). Примеры использования

Синтаксис функции each:

// array или object - массив или объект, элементы или свойства которого необходимо перебрать
// callback - функция, которая будет выполнена для каждого элемента массива или свойства объекта
$.each(array или object,callback);

Работу с функцией each разберём на примерах.

Пример №1. В нём выполним переберор всех элементов массива (array).

// массив, состоящий из 3 строк
var arr = ['Автомобиль','Грузовик','Автобус'];

// переберём массив arr
$.each(arr,function(index,value){

  // действия, которые будут выполняться для каждого элемента массива
  // index - это текущий индекс элемента массива (число)
  // value - это значение текущего элемента массива
  
  //выведем индекс и значение массива в консоль
  console.log('Индекс: ' + index + '; Значение: ' + value);

});

/*
Результат (в консоли):
Индекс: 0; Значение: Автомобиль
Индекс: 1; Значение: Грузовик
Индекс: 2; Значение: Автобус
*/

В вышеприведённом коде функция each используется для перебора массива. Функция имеет 2 обязательных параметра. Первый параметр - это сущность (массив или объект), элементы (свойства) которой необходимо перебрать. В данном случае - это массив arr. Второй параметр - это функция обратного вызова, которая будет выполнена для каждого элемента (в данном случае) массива. Она имеет 2 параметра, которые доступны внутри неё посредством соответствующих переменных. Первый параметр - это порядковый номер элемента (отсчёт выполняется с 0). Второй параметр - это значение текущего элемента массива.

Пример №2. В этом примере осуществим перебор всех свойств объекта.

// объект smartphone, имеющий 5 свойств
var smartphone = {
  "name": "LG G5 se",
  "year": "2016",
  "screen-size": "5.3",
  "screen-resolution": "2560 x 1440",
  "os" : "Android 6.0 (Marshmallow)"
};

// переберём объект smartphone
$.each(smartphone, function( key, value ) {

  // действия, которые будут выполняться для каждого свойства объекта
  // key - текущее имя свойства массива
  // value - значение текущего свойства объекта
 
  // выведем имя свойства и его значение в консоль
  console.log( 'Свойство: ' +key + '; Значение: ' + value );

});

/*
Результат (в консоли):
Свойство: name; Значение: LG G5 se
Свойство: year; Значение: 2016
Свойство: screen-size; Значение: 5.3
Свойство: screen-resolution; Значение: 2560 x 1440
Свойство: os; Значение: Android 6.0 (Marshmallow)
*/

Функция each может использоваться для перебора JavaScript объектов. Отличие её использования заключается только в том, что параметры функции обратного вызова имеют другие значения. Первый параметр хранит название свойства объекта, а второй - значение этого свойства.

Пример №3. В нём осуществим перебор более сложной структуры (рассмотрим, как использовать вложенные each).

// объект, состоящий из 2 свойств. Каждое свойство этого объект имеет в качестве значения массив, элементами которого являются тоже объекты
var articles = {
  "Bootstrap": [
    {"id":"1", "title":"Введение"},
    {"id":"2", "title":"Как установить"},
    {"id":"3", "title":"Сетка"}
  ],
  "JavaScript": [
    {"id":"4", "title":"Основы"},
    {"id":"5", "title":"Выборка элементов"}
  ]  
};

$.each(articles,function(key,data) {
  console.log('Раздел: ' + key);
  $.each(data, function(index,value) {
    console.log('Статья: id = ' + value['id'] + '; Название = '+ value['title']);
  });
});

/*
Результат:
Раздел: Bootstrap
Статья: id = 1; Название = Введение
Статья: id = 2; Название = Как установить
Статья: id = 3; Название = Сетка
Раздел: JavaScript
Статья: id = 4; Название = Основы
Статья: id = 5; Название = Выборка элементов
*/

Как прервать each (выйти из цикла)

Прерывание (break) цикла each осуществляется с помощью оператора return, который должен возвращать значение false.

Например, прервём выполнение цикла each после того как найдём в массиве arr число 7:

// массив, состоящий из 5 чисел
var arr = [5, 4, 7, 17, 19];

// число, которое необходимо найти
var find = 7;

// переберём массив arr
$.each(arr, function (index, value) {
  // если необходимое число найдено, то..
  if (value === find) {
    // вывести его в консоль
    console.log('Ура! Число ' + find + ' найдено! Данное число имеет индекс: ' + index);
    // прервать выполнение цикла
    return false;
  } else {
  // иначе вывести в консоль текущее число
  console.log('Текущее число: ' + value);
  }
});

/* Результат (в консоли):
Текущее число: 5
Текущее число: 4
Ура! Число 7 найдено! Данное число имеет индекс: 2
*/

Как перейти к следующей итерации (each continue)

В each прерывание выполнения текущей итерации и переход к следующей осуществляется с помощью оператора return, который должен иметь значение отличное от false.

// массив, состоящий из чисел
var arr = [3, 5, 4, 9, 17, 19, 30, 35, 40];

// массив, который должен содержать все элементы массива arr, кроме чётных чисел
var newarr = [];

// переберём массив arr
$.each(arr, function (index, value) {

  // если элемент чётный, то пропустим его
  if (value % 2 === 0) {
    // прервём выполнение текущей итерации и перейдём к следующей
    return;
  }
  // добавить в массив newarr значение value
  newarr.push(value);

});

console.log('Исходный массив (arr): ' + arr.join());
console.log('Результирующий массив (newarr): ' + newarr.join());

/* Результат (в консоли):
Исходный массив (arr): 3,5,4,9,17,19,30,35,40
Результирующий массив (newarr): 3,5,9,17,19,35
*/