Сбой org.xmlpull.v1.XmlPullParserException от android.graphics.drawable.Drawable.createFromXmlInner

Нерушимость

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

Исправление вашего подхода

Давайте сначала посмотрите на устранение некоторых проблем в вашей функции:

let findValues = x => {
  if (R.has('values')(x)) {
    let availableValues = R.prop('values')(x);
    let selectedValues = R.pluck('a')(availableValues);
    R.map(R.evolve({
      availableValues: availableValues,
      selectedValues: selectedValues
    }))
  }
}

Первая, самая очевидная проблема в том, что эта функция ничего не возвращает. Как упоминалось выше, Ramda не мутирует ваши данные. Таким образом, функция, которая ничего не возвращает, бесполезна, если ее поставить в map Рамды . Мы можем исправить это, возвращая результат вызова map(evolve) и возвращая исходное значение, когда условие if не выполнено:

let findValues = x => {
  if (R.has('values')(x)) {
    let availableValues = R.prop('values')(x);
    let selectedValues = R.pluck('a')(availableValues);
    return R.map(R.evolve({
      availableValues: availableValues,
      selectedValues: selectedValues
    }))
  }
  return x;
}

Затем вызов map не имеет смысла. evolve уже выполняет итерацию свойств объекта. Поэтому мы можем удалить это. Но нам также нужно применить evolve к вашему входному значению:

let findValues = x => {
  if (R.has('values')(x)){
    let availableValues = R.prop('values')(x);
    let selectedValues = R.pluck('a')(availableValues);
    return R.evolve({
      availableValues: availableValues,
      selectedValues: selectedValues
    }, x)
  }
  return x;
}

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

evolve({
  a: n => n * 10,
  b: n => n + 5
})({a: 1, b: 2, c: 3}) //=> {a: 10, b: 7, c: 3}

Обратите внимание, что значения свойств объекта, заданного в evolve, являются функциями. Этот код предоставляет значения. Мы можем обернуть эти значения с помощью R.always через availableValues: R.always(availableValues), но я думаю, что проще использовать лямбда с параметром «_», что означает, что параметр неважен: availableValues: _ => availableValues. Вы также можете написать availableValues: () => available values, но подчеркивание демонстрирует тот факт, что обычное значение игнорируется.

Фиксация этого получает функцию, которая работает:

let findValues = x => {
  if (R.has('values')(x)){
    let availableValues = R.prop('values')(x);
    let selectedValues = R.pluck('a')(availableValues);
    return R.evolve({
      availableValues: _ => availableValues,
      selectedValues: _ => selectedValues
    }, x)
  }
  return x;
}

let arrObj = [{myValues: []}, {availableValues: [], myValues: [], selectedValues: [], values: [{a: "x", b: "1"}, {a: "y", b: "2"}]}];

console.log(R.map(findValues, arrObj))

Если вы запустите этот фрагмент здесь, вы также увидите интересную точку, что полученное свойство availableValues является ссылкой на исходный values, а не отдельной копией из этого. Это помогает показать, что Ramda повторно использует то, что может, из ваших исходных данных. Вы также можете увидеть это, отметив, что R.map(findValues, arrObj)[0] === arrObj[0] //=> true.

Другие подходы

Я написал свои собственные версии этого, не начиная с вашего. Вот одна работающая функция:

const findValues = when(
  has('values'),
  x => evolve({
    availableValues: _ => prop('values', x),
    selectedValues: _ => pluck('a', prop('values', x))
  }, x)
)

Обратите внимание на использование when , в котором фиксируется понятие «когда этот предикат истинен для вашего значения», используйте следующее преобразование , в противном случае используйте свое первоначальное значение. " Мы передаем предикат has('values'), по существу такой же, как и выше. Наша трансформация похожа на вашу, используя evolve, но она пропускает временные переменные при незначительной стоимости повторения вызова prop .

Что-то меня беспокоит эта версия. Использование этих лямбда с «_» действительно является неправильным использованием evolve. Я думаю, что это чище:

const findValues = when(
  has('values'),
  x => merge(x, {
    availableValues: prop('values', x),
    selectedValues: pluck('a', prop('values', x))
  })
)

Здесь мы используем merge, который представляет собой чистую функциональную версию Object.assign , добавляя параметры второго объекта к тем

Это то, что я бы выбрал.

Решение плеера

Поскольку я начал писать этот ответ, Скотт Кристофер опубликовал еще один один, по существу

const findValues = R.map(R.when(R.has('values'), R.applySpec({
  myValues:        R.prop('myValues'),
  values:          R.prop('values'),
  availableValues: R.prop('values'),
  selectedValues:  R.o(R.pluck('a'), R.prop('values'))
})))

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

Пошаговое

Это не ужасно сложное преобразование, но это нетривиально. Один простой способ построить что-то подобное - это создать его на очень незначительных этапах. Я часто делаю это в Ramda REPL , поэтому я могу видеть результаты, когда я иду.

Мой процесс выглядел примерно так:

Шаг 1 g16]

Убедитесь, что я правильно преобразовываю только правильные значения:

const findValues = when(
  has('values'), 
  always('foo')
)
map(findValues, arrObj) //=> [{myValues: []}, "foo"]

Шаг 2

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

const findValues = when(
  has('values'), 
  keys
)
map(findValues, arrObj) 
//=> [{myValues: []}, ["myValues", "values", "availableValues", "selectedValues"]]

Здесь identity будет работать так же хорошо, как keys . Все, что демонстрирует, что правильный объект передан, будет прекрасным.

Шаг 3

Проверьте, что merge будет работать правильно здесь.

const findValues = when(
  has('values'), 
  x => merge(x, {foo: 'bar'})
)
map(findValues, arrObj) 
//=> [
//     {myValues: []}, 
//     {
//       myValues: [], 
//       values: [{a: "x", b: "1"}, {a: "y", b: "2"}],
//       availableValues: [], 
//       selectedValues: [], 
//       foo: "bar"
//     }
//   ]

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

Шаг 4

Теперь, фактически преобразуйте первое значение, которое я хочу:

const findValues = when(
  has('values'),
  x => merge(x, {
    availableValues: prop('values', x)
  })
)
map(findValues, arrObj) 
//=> [
//     {myValues: []}, 
//     {
//       myValues: [], 
//       values: [{a: "x", b: "1"}, {a: "y", b: "2"}],
//       availableValues: [{a: "x", b: "1"}, {a: "y", b: "2"}],
//       selectedValues: []
//     }
//   ]

Шаг 5

Это делает то, что я хочу. Теперь добавьте другое свойство:

const findValues = when(
  has('values'),
  x => merge(x, {
    availableValues: prop('values', x),
    selectedValues: pluck('a', prop('values', x))
  })
)
map(findValues, arrObj) 
//=> [
//     {myValues: []}, 
//     {
//       myValues: [], 
//       values: [{a: "x", b: "1"}, a: "y", b: "2"}],
//       availableValues: [{a: "x", b" "1"}, {a: "y", b: "2"}], 
//       selectedValues: ["x", "y"]
//     }
//   ]

И это, наконец, дает результат, который я хочу.

Это быстрый процесс. Я могу запустить и протестировать очень быстро в REPL, итерации моего решения, пока я не получу то, что делает то, что я хочу.

0
задан Hong 20 January 2019 в 00:48
поделиться