从for循环转换为forEach / map / some ..等

时间:2017-07-04 16:07:11

标签: javascript

是否可以在以下代码段中不使用for循环?

const states = [
  { a: 1 },
  { b: 1 },
  { b: 2, c: 1 }
];

const defaultState = {
  a: 0,
  b: 0,
  c: 0
};

const getRange = prop => {
  const range = [];

  for (let i = 0; i < states.length; i += 1) {
    let prevState;

    for (let j = i - 1; j >= 0; j -= 1) {
      prevState = states[j] && states[j][prop];
      if (prevState) break;
    }

    range[i] = states[i][prop] || (prevState || defaultState[prop]);
  }

  return range;
};

getRange('a') // [1, 1, 1]
getRange('b') // [0, 1, 2]
getRange('c') // [0, 0, 1]

它应该只使用JavaScript而不依赖于任何其他库,我尝试使用forEach()和some(),但无法复制当前行为。这是为了探索语言目的。

3 个答案:

答案 0 :(得分:2)

const states = [
  { a: 1 },
  { b: 1 },
  { b: 2, c: 1 }
];

const defaultState = {
  a: 0,
  b: 0,
  c: 0
};

const getRange = prop => {
  return states.reduce((res, o, i) => {
    res.push( o[prop] || res[i - 1] || defaultState[prop] );
    return res;
  }, []);
};

console.log(getRange('a')); // [1, 1, 1]
console.log(getRange('b')); // [0, 1, 2]
console.log(getRange('c')); // [0, 0, 1]

res是结果数组。对于我们推送的o数组中的每个对象states

res.push( o[prop] || res[i - 1] || defaultState[prop] );
// or:
res[i] = o[prop] || res[i - 1] || defaultState[prop];

或者:

  • 此当前对象o状态,
  • 记录的先前状态(存储在res[i - 1])(前一状态),
  • 或来自defaultState的默认状态。

在我的代码中,reduce替换了代码中的外部forres[i - 1]替换了内部for(因为没有必要循环直到第一个元素到得到我们已经知道它只落后一步的先前状态。

修改

要将0视为使用它:

res.push( (o[prop] || o[prop] == 0)? o[prop]:               // if o[prop] is truthy or equal to 0 then use it
          (res[i - 1] || res[i - 1] == 0)? res[i - 1]:      // otherwise (o[prop] is neither truthy nor equal to 0) then if res[i - 1] is truthy or equal to 0 then use res[i - 1]
          defaultState[prop] );                             // otherwise just use the default value no matter whether it is truthy or not (that's the point of default values anyway)

或:

res.push( !isNaN(o[prop])? o[prop]:                         // if o[prop] is a valid number use it
          !isNaN(res[i - 1])? res[i - 1]:                   // otherwise, if res[i - 1] is a valid number then use it
          defaultState[prop] );                             // otherwise, use the default value

答案 1 :(得分:1)

非常直译 - 每个循环都成为方法调用 - 代码将是

var fieldSchema = ListBuffer[StructField]()
val columns = mydf.columns

 for (i <- 0 until columns.length) {
      val columns = mydf.columns
      val colName = columns(i)
      fieldSchema += StructField(colName, mydf.schema(i).dataType, true, null)
    }
 val schema = StructType(fieldSchema.toList)
 val newdf = sqlContext.createDataFrame(df.rdd, schema) << df is the original dataframe
 newdf.printSchema() << this prints the new applied schema
 println("newdf count:"+newdf.count()) << this fails with null pointer exception

答案 2 :(得分:0)

const states = [{ a: 1 }, { b: 1 }, { b: 2, c: 1 }];
const defaultState = {a: 0, b: 0, c: 0};

function getRange(prop) {
  let prev;
  return states.map(s =>
      prev = s[prop] || prev || defaultState[prop]);
};

console.log(getRange('a'));
console.log(getRange('b'));
console.log(getRange('c'));