setState родителя из дочернего компонента с парами значений ключа в React? [Дубликат]

Вы не можете получить доступ к любым абстракциям «Исправлена» (RDDs, DataFrames, Datasets, SparkSession ...) Spark из функции, переданной в одну из преобразований DataFrame / RDD Spark. Вы также не можете обновлять измененные объекты на стороне драйвера из этих функций.

В вашем случае - вы пытаетесь использовать prodRows и selection (оба являются DataFrames) в функции, переданной в DataFrame.foreach. Вы также пытаетесь обновить listOfProducts (локальную драйверную переменную) из этой же функции.

Почему?

  • DataFrames, RDD и SparkSession существуют только в приложении Driver. Они служат «ручкой» для доступа к данным, распределенным по кластеру рабочих машин.
  • Функции, переданные в преобразования RDD / DataFrame, получают serialized и отправляются в этот кластер, которые должны выполняться на разделах данных на каждой рабочей машине. Когда сериализованные DataFrames / RDD получаются десериализованными на этих машинах - они бесполезны, они не могут представлять данные в кластере, поскольку они представляют собой только полные копии тех, которые созданы в приложении драйвера, что фактически поддерживает соединение для кластерных машин
  • По той же причине попытка обновления драйверов переменных не будет выполнена: переменные (начинающиеся как пустые, в большинстве случаев) будут сериализованы, десериализованы на каждом из рабочие, обновляются локально на рабочих и остаются там ... исходная переменная со стороны водителя останется неизменной

Как вы можете это решить? При работе с Spark, особенно с DataFrames, вы должны стараться избегать «итерации» над данными и вместо этого использовать декларативные операции DataFrame. В большинстве случаев, когда вы хотите ссылаться на данные другого DataFrame для каждой записи в вашем DataFrame, вы хотите использовать join для создания нового DataFrame с записями, объединяющими данные из двух DataFrames.

В этом конкретном случае, это примерно эквивалентное решение, которое делает то, что вы пытаетесь сделать, если мне удастся это сделать правильно. Попытайтесь использовать это и прочитайте документацию DataFrame, чтобы выяснить детали:

import org.apache.spark.sql.expressions.Window
import org.apache.spark.sql.functions._
import spark.implicits._

val numRecProducts = 10

val result = prodRows.as("left")
  // self-join by gender:
  .join(prodRows.as("right"), $"left.gender_PK" === $"right.gender_PK" || $"right.gender_PK" === "UNISEX")
  // limit to 10 results per record:
  .withColumn("rn", row_number().over(Window.partitionBy($"left.product_PK").orderBy($"right.product_PK")))
  .filter($"rn" <= numRecProducts).drop($"rn")
  // group and collect_list to create products column:
  .groupBy($"left.product_PK" as "product_PK")
  .agg(collect_list(struct($"right.product_PK", lit(1))) as "products")
109
задан Christophe 10 October 2012 в 20:47
поделиться

10 ответов

Как и многие другие, я часто предпочитаю передавать функцию options object в функцию вместо передачи длинного списка параметров, но это действительно зависит от точного контекста.

Я использую читаемость кода как тест лакмуса.

Например, если у меня есть этот вызов функции:

checkStringLength(inputStr, 10);

Я думаю, что код вполне читабельный, как есть, и передача отдельных параметров просто прекрасна.

С другой стороны, существуют функции с такими вызовами:

initiateTransferProtocol("http", false, 150, 90, null, true, 18);

Полностью нечитабельно, если вы не проводите какое-либо исследование. С другой стороны, этот код хорошо читается:

initiateTransferProtocol({
  "protocol": "http",
  "sync":      false,
  "delayBetweenRetries": 150,
  "randomVarianceBetweenRetries": 90,
  "retryCallback": null,
  "log": true,
  "maxRetries": 18
 });

Это скорее искусство, чем наука, но если бы мне пришлось называть эмпирические правила:

Использовать параметры параметр, если:

  • У вас более четырех параметров
  • Любой из параметров является необязательным
  • Вам приходилось искать функцию для выяснить, какие параметры он принимает
  • Если кто-то пытается задушить вас, крича «ARRRRRG!»
106
ответ дан ravish.hacker 26 August 2018 в 05:17
поделиться

Возможно, я немного опоздал на вечеринку с этим ответом, но я искал мнения других разработчиков по этой теме и наткнулся на эту тему.

Я очень не согласен с большинством респондентов и сторон с подходом «множественных аргументов». Мой главный аргумент заключается в том, что он не поощряет другие анти-шаблоны, такие как «мутация и возвращение объекта param» или «передача одного и того же объекта param на другие функции». Я работал в кодовых базах, которые сильно злоупотребляли этим анти-шаблоном, и код отладки, который делает это быстро, становится невозможным. Я думаю, что это очень специфичное для Javascript правило, поскольку Javascript не сильно типизирован и допускает такие произвольно структурированные объекты.

Мое личное мнение заключается в том, что разработчики должны быть явными при вызове функций, избегать прохождения избыточные данные и избегать модификации по ссылке. Дело не в том, что эти шаблоны не позволяют писать сжатый, правильный код. Я просто чувствую, что для вашего проекта намного легче впасть в плохие методы разработки.

Рассмотрим следующий ужасный код:

function main() {
    const x = foo({
        param1: "something",
        param2: "something else",
        param3: "more variables"
    });

    return x;
}

function foo(params) {
    params.param1 = "Something new";
    bar(params);
    return params;
}


function bar(params) {
    params.param2 = "Something else entirely";
    const y = baz(params);
    return params.param2;
}

function baz(params) {
    params.params3 = "Changed my mind";
    return params;
}

Не только этот тип требует более явного документацию, чтобы указать намерение, но она также оставляет место для неопределенных ошибок. Что делать, если разработчик изменяет param1 в bar()? Как долго, по-твоему, понадобится проглядеть кодовую базу достаточного размера, чтобы поймать это? По общему признанию, этот пример немного неискренен, поскольку предполагает, что разработчики уже совершили несколько анти-шаблонов к этому моменту. Но это показывает, как передающие объекты, содержащие параметры, позволяют больше места для ошибки и двусмысленности, требуя большей степени добросовестности и соблюдения корректности const.

Только мои двухценты в этом вопросе!

1
ответ дан ajxs 26 August 2018 в 05:17
поделиться

Несколько аргументов в основном относятся к обязательным параметрам. Нет ничего плохого в них.

Если у вас есть дополнительные параметры, он становится сложным. Если один из них полагается на других, так что у них есть определенный порядок (например, четвертый нуждается в третьем), вы все равно должны использовать несколько аргументов. Практически все родные EcmaScript и DOM-методы работают так. Хорошим примером является метод open XMLHTTPrequests , где последние 3 аргумента являются необязательными - правило похоже на «без пароля без пользователя» (см. Также MDN docs ).

Опционные объекты пригождаются в двух случаях:

  • У вас так много параметров, что это запутывает: «Именование» поможет вам, вы надеваете Не нужно беспокоиться о порядке их (особенно если они могут измениться)
  • У вас есть дополнительные параметры. Объекты очень гибкие, и без какого-либо заказа вы просто передаете то, что вам нужно, и ничего больше (или undefined s).

В вашем случае я рекомендую map(nodeList, callback, options). nodelist и callback требуются, остальные три аргумента происходят только изредка и имеют разумные значения по умолчанию.

Другим примером является JSON.stringify . Вы можете использовать параметр space без передачи функции replacer - тогда вы должны вызвать …, null, 4). Объект arguments мог быть лучше, хотя его не очень разумно только для 2 параметров.

22
ответ дан Bergi 26 August 2018 в 05:17
поделиться

Я бы посмотрел на большие проекты javascript.

Такие вещи, как google map, вы часто увидите, что объекты-объекты, требующие объекта, требуют объекта, но функции требуют параметров. Я думаю, что это связано с аргументами OPTION.

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

Javascript также имеет объект arguments. https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Functions_and_function_scope/arguments

0
ответ дан dm03514 26 August 2018 в 05:17
поделиться

Использование подхода «параметры как объект» будет лучше. Вам не нужно беспокоиться о порядке свойств и есть большая гибкость в том, какие данные передаются (например, необязательные параметры)

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

options={
    nodeList:...,
    callback:...,
    thisObject:...,
    fromIndex:...,
    toIndex:...
}

function1(options){
    alert(options.nodeList);
}

function2(options){
    alert(options.fromIndex);
}
11
ответ дан Fluidbyte 26 August 2018 в 05:17
поделиться

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

2
ответ дан happyCoda 26 August 2018 в 05:17
поделиться

Для функции, которая обычно использует некоторые предопределенные аргументы, вам лучше использовать объект option. Простой пример будет чем-то вроде функции, которая получает бесконечное количество аргументов, таких как: setCSS ({height: 100}, {width: 200}, {background: "# 000"}).

1
ответ дан Ilya Sidorovich 26 August 2018 в 05:17
поделиться

Ваш комментарий к вопросу:

в моем примере последние три являются необязательными.

Так почему бы не сделать это? (Примечание: это довольно грубый Javascript. Обычно я использую хэш default и обновляю его с помощью опций, переданных с помощью Object.extend или JQuery.extend или аналогичный.)

function map(nodeList, callback, options) {
   options = options || {};
   var thisObject = options.thisObject || {};
   var fromIndex = options.fromIndex || 0;
   var toIndex = options.toIndex || 0;
}

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

map(nodeList, callback);
map(nodeList, callback, {});
map(nodeList, callback, null);
map(nodeList, callback, {
   thisObject: {some: 'object'},
});
map(nodeList, callback, {
   toIndex: 100,
});
map(nodeList, callback, {
   thisObject: {some: 'object'},
   fromIndex: 0,
   toIndex: 100,
});
5
ответ дан Izkata 26 August 2018 в 05:17
поделиться

Это зависит.

Основываясь на моем наблюдении за дизайном этих популярных библиотек, рассмотрим сценарии использования объекта option:

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

И сценарии использования списка параметров:

  • Список параметров короткий (& lt; = 4).
  • Требуется большинство или всех параметров.
  • Дополнительные параметры находятся в определенном порядке. (т. е .: $ .get)
  • Легко рассказать значение параметров по имени API.
3
ответ дан Lynn Ning 26 August 2018 в 05:17
поделиться

Я думаю, что если вы что-то создаете или называете метод объекта, вы хотите использовать объект options. Если это функция, которая работает только с одним или двумя параметрами и возвращает значение, предпочтительнее список аргументов.

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

В вашем примере я сделал бы map(nodeList, callback, options). Нумеру и обратный вызов требуются, довольно легко рассказать, что происходит, просто прочитав звонок, и это похоже на существующие функции карты. Любые другие опции могут быть переданы как дополнительный третий параметр.

7
ответ дан Trevor Dixon 26 August 2018 в 05:17
поделиться
Другие вопросы по тегам:

Похожие вопросы: